No Lecture — Lab Week
Fluorescent Pixel Art — Bacterial Canvas
Using the opentrons-art.rcdonovan.com GUI, a pixel-art design was created by selecting coordinates on an agar plate canvas and assigning fluorescent protein colors to each dot. The resulting coordinate map — organized by fluorescent protein — was exported and used to generate the Opentrons OT-2 Python script below. Each colored point corresponds to a 1 µL dispense of a specific fluorescent protein solution onto the agar surface; the robot pipettes each color in sequence, aspirating from a 96-well PCR strip loaded with the corresponding protein preparations.
The design uses 13 distinct fluorescent proteins, each dispensed from a separate well of the PCR strip on the aluminium block: mKO2 (orange, 70 points), mTurquoise2 (cyan, 41 points), mRFP1 (red, 36 points), mHoneydew (pale green, 8 points), mAzamiGreen (green, 14 points), mkate2 (far-red, 12 points), tdTomato (orange-red, 19 points), EGFP (green, 10 points), PA-GFP (photoactivatable, 6 points), mCherry (red, 6 points), mVenus (yellow, 2 points), Electra2 (5 points), and eqFP578 (1 point). Each point = 1 µL, dispensed using a P20 single-channel GEN2 pipette with a maximum aspirate volume of 18 µL per tip pickup.
The composition is made up of six simple but visually distinct motifs, each assigned to a different region of the agar plate and rendered in a different fluorescent protein color. The goal was legibility at the scale of a petri dish — bold shapes that read clearly under UV illumination.
The six motifs were arranged to distribute spectral emission across the plate spatially — warm tones (orange, red) on the left, cool tones (cyan, green) on the right and center, with the far-red mKate2 and mRFP1 acting as anchors. Under a standard fluorescence imager with sequential excitation channels, each motif would appear in a distinct channel image, and the composite would reconstruct the full composition. The Yeezus cross was chosen as the dominant motif because its pixel form is architecturally simple — a rectangle intersected by a bar — and because its cultural specificity makes the plate immediately readable as an intentional design rather than a random distribution of protein dots.
from opentrons import types
import string
metadata = {
'protocolName': 'HTGAA Opentrons Art - Week 3', # ← reemplaza con tu nombre
'author': 'HTGAA 2026',
'source': 'HTGAA 2026',
'apiLevel': '2.20'
}
# ──────────────────────────────────────────────
# Parámetros globales
# ──────────────────────────────────────────────
Z_VALUE_AGAR = 2.0 # offset z sobre el agar (mm)
POINT_SIZE = 1 # µL por punto
# ──────────────────────────────────────────────
# Coordenadas de cada proteína fluorescente
# (generadas desde opentrons-art.rcdonovan.com)
# ──────────────────────────────────────────────
mko2_points = [
(13.2,26.4), (-26.4,24.2), (-24.2,24.2), (-22,24.2), (-19.8,24.2), (-17.6,24.2),
(13.2,24.2), (-26.4,22), (-24.2,22), (-22,22), (-19.8,22), (13.2,22),
(-28.6,19.8), (-26.4,19.8), (-24.2,19.8), (-22,19.8), (-19.8,19.8), (-13.2,19.8),
(11,19.8), (13.2,19.8), (15.4,19.8), (-28.6,17.6), (-26.4,17.6), (-24.2,17.6),
(-22,17.6), (-19.8,17.6), (-17.6,17.6), (-15.4,17.6), (-13.2,17.6), (-11,17.6),
(4.4,17.6), (6.6,17.6), (8.8,17.6), (11,17.6), (13.2,17.6), (15.4,17.6),
(17.6,17.6), (19.8,17.6), (22,17.6), (-30.8,15.4), (-28.6,15.4), (-26.4,15.4),
(-24.2,15.4), (-22,15.4), (-19.8,15.4), (-17.6,15.4), (-15.4,15.4), (-13.2,15.4),
(-11,15.4), (11,15.4), (15.4,15.4), (-22,13.2), (-19.8,13.2), (-17.6,13.2),
(-15.4,13.2), (-13.2,13.2), (8.8,13.2), (17.6,13.2), (-22,11), (-19.8,11),
(-17.6,11), (-15.4,11), (6.6,11), (19.8,11), (-22,8.8), (-19.8,8.8),
(-17.6,8.8), (-22,6.6), (-19.8,6.6), (-22,4.4)
]
mrfp1_points = [
(-24.2,-6.6), (-22,-6.6), (-17.6,-6.6), (-15.4,-6.6), (-26.4,-8.8), (-24.2,-8.8),
(-22,-8.8), (-19.8,-8.8), (-17.6,-8.8), (-15.4,-8.8), (-13.2,-8.8), (-26.4,-11),
(-24.2,-11), (-22,-11), (-19.8,-11), (-17.6,-11), (-15.4,-11), (-13.2,-11),
(-24.2,-13.2), (-22,-13.2), (-19.8,-13.2), (-17.6,-13.2), (-15.4,-13.2),
(-22,-15.4), (-19.8,-15.4), (-17.6,-15.4), (19.8,-15.4), (22,-15.4), (24.2,-15.4),
(-19.8,-17.6), (19.8,-17.6), (22,-17.6), (24.2,-17.6), (19.8,-19.8),
(22,-19.8), (24.2,-19.8)
]
tdtomato_points = [
(11,-6.6), (13.2,-6.6), (15.4,-6.6), (11,-8.8), (15.4,-8.8), (13.2,-11),
(2.2,-15.4), (4.4,-17.6), (6.6,-17.6), (2.2,-19.8), (4.4,-19.8), (6.6,-19.8),
(11,-24.2), (13.2,-24.2), (15.4,-24.2), (11,-26.4), (15.4,-26.4),
(11,-28.6), (13.2,-28.6)
]
mturquoise2_points = [
(8.8,-6.6), (17.6,-6.6), (6.6,-8.8), (17.6,-8.8), (19.8,-8.8), (4.4,-11),
(6.6,-11), (8.8,-11), (17.6,-11), (19.8,-11), (22,-11), (2.2,-13.2),
(4.4,-13.2), (6.6,-13.2), (8.8,-13.2), (11,-13.2), (15.4,-13.2), (17.6,-13.2),
(19.8,-13.2), (24.2,-13.2), (6.6,-15.4), (8.8,-15.4), (17.6,-15.4),
(8.8,-19.8), (17.6,-19.8), (2.2,-22), (4.4,-22), (6.6,-22), (8.8,-22),
(11,-22), (15.4,-22), (17.6,-22), (19.8,-22), (22,-22), (24.2,-22),
(4.4,-24.2), (8.8,-24.2), (19.8,-24.2), (22,-24.2), (6.6,-26.4), (8.8,-26.4),
(17.6,-26.4), (19.8,-26.4), (17.6,-28.6)
]
mkate2_points = [
(13.2,-13.2), (11,-15.4), (13.2,-15.4), (15.4,-15.4), (8.8,-17.6), (11,-17.6),
(15.4,-17.6), (17.6,-17.6), (11,-19.8), (13.2,-19.8), (15.4,-19.8), (13.2,-22)
]
eqfp578_points = [(13.2,-17.6)]
pa_gfp_points = [(8.8,-8.8), (11,-11), (22,-13.2), (6.6,-24.2), (17.6,-24.2), (8.8,-28.6)]
mcherry_points = [(13.2,-8.8), (15.4,-11), (4.4,-15.4), (2.2,-17.6), (13.2,-26.4), (15.4,-28.6)]
egfp_points = [(-28.6,24.2), (-28.6,22), (-30.8,17.6), (-24.2,13.2), (-24.2,11),
(-24.2,8.8), (-26.4,6.6), (-24.2,6.6), (-24.2,4.4), (-24.2,2.2)]
mazamigreen_points = [
(-2.2,37.4), (0,37.4), (4.4,37.4), (11,35.2), (13.2,35.2), (-6.6,33), (0,33),
(17.6,33), (-6.6,30.8), (-2.2,30.8), (2.2,30.8), (-6.6,28.6), (2.2,28.6), (0,26.4)
]
mvenus_points = [(-4.4,35.2), (-2.2,26.4)]
electra2_points = [(-2.2,2.2), (-4.4,0), (0,0), (-2.2,-2.2), (-2.2,-4.4)]
mhoneydew_points = [(-2.2,4.4), (-6.6,0), (-2.2,0), (2.2,0), (-4.4,-4.4), (0,-4.4),
(-2.2,-6.6), (-2.2,-8.8)]
point_name_pairing = [
("mko2", mko2_points),
("mrfp1", mrfp1_points),
("tdtomato", tdtomato_points),
("mturquoise2", mturquoise2_points),
("mkate2", mkate2_points),
("eqfp578", eqfp578_points),
("pa_gfp", pa_gfp_points),
("mcherry", mcherry_points),
("egfp", egfp_points),
("mazamigreen", mazamigreen_points),
("mvenus", mvenus_points),
("electra2", electra2_points),
("mhoneydew", mhoneydew_points),
]
# ──────────────────────────────────────────────
# Deck setup
# ──────────────────────────────────────────────
TIP_RACK_DECK_SLOT = 9
COLORS_DECK_SLOT = 6
AGAR_DECK_SLOT = 5
PIPETTE_STARTING_TIP_WELL = 'A1'
# Mapa pozo → color (placa PCR strip 96-well)
well_colors = {
'A1': 'sfGFP', 'A2': 'mRFP1', 'A3': 'mKO2',
'A4': 'Venus', 'A5': 'mKate2_TF', 'A6': 'Azurite',
'A7': 'mCerulean3','A8': 'mClover3', 'A9': 'mJuniper',
'A10':'mTurquoise2','A11':'mBanana', 'A12':'mPlum',
'B1': 'Electra2', 'B2': 'mWasabi', 'B3': 'mScarlet_I',
'B4': 'mPapaya', 'B5': 'eqFP578', 'B6': 'tdTomato',
'B7': 'DsRed', 'B8': 'mKate2', 'B9': 'EGFP',
'B10':'mRuby2', 'B11':'TagBFP', 'B12':'mChartreuse_TF',
'C1': 'mLychee_TF','C2': 'mTagBFP2', 'C3': 'mEGFP',
'C4': 'mNeonGreen','C5': 'mAzamiGreen','C6': 'mWatermelon',
'C7': 'avGFP', 'C8': 'mCitrine', 'C9': 'mVenus',
'C10':'mCherry', 'C11':'mHoneydew', 'C12':'TagRFP',
'D1': 'mTFP1', 'D2': 'Ultramarine','D3': 'ZsGreen1',
'D4': 'mMiCy', 'D5': 'mStayGold2','D6': 'PA_GFP',
}
# Volumen acumulado por color (para control de pozo activo)
volume_used = {k: 0 for k, _ in point_name_pairing}
# ──────────────────────────────────────────────
# Utilidades
# ──────────────────────────────────────────────
def update_volume_remaining(current_color, quantity_to_aspirate):
"""Avanza al siguiente pozo cuando el actual supera 250 µL."""
rows = string.ascii_uppercase
for well, color in list(well_colors.items()):
if color.lower() == current_color.lower():
if (volume_used[current_color] + quantity_to_aspirate) > 250:
row, col = well[0], well[1:]
next_well = f"{rows[rows.index(row) + 1]}{col}"
del well_colors[well]
well_colors[next_well] = current_color
volume_used[current_color] = quantity_to_aspirate
else:
volume_used[current_color] += quantity_to_aspirate
break
def run(protocol):
protocol.home()
# ── Labware ──────────────────────────────
tips_20ul = protocol.load_labware(
'opentrons_96_tiprack_20ul', TIP_RACK_DECK_SLOT, 'Tips 20 µL')
pipette_20ul = protocol.load_instrument(
"p20_single_gen2", "right", [tips_20ul])
temperature_plate = protocol.load_labware(
'opentrons_96_aluminumblock_generic_pcr_strip_200ul', COLORS_DECK_SLOT)
agar_plate = protocol.load_labware(
'htgaa_agar_plate', AGAR_DECK_SLOT, 'Agar Plate')
agar_plate.set_offset(x=0.00, y=0.00, z=Z_VALUE_AGAR)
center_location = agar_plate['A1'].top()
pipette_20ul.starting_tip = tips_20ul.well(PIPETTE_STARTING_TIP_WELL)
# ── Helpers ──────────────────────────────
def dispense_and_jog(pipette, volume, location):
"""
Mueve 2 mm sobre el punto, dispensa y retrocede.
FIX: usamos offset relativo (z=2) en lugar de absoluto.
"""
assert isinstance(volume, (int, float))
above = location.move(types.Point(z=2)) # ← corregido (era z=location.point.z+2)
pipette.move_to(above)
pipette.dispense(volume, location)
pipette.move_to(above)
def location_of_color(color_string):
for well, color in well_colors.items():
if color.lower() == color_string.lower():
return temperature_plate[well]
raise ValueError(f"Color no encontrado: {color_string}")
# ── Impresión ─────────────────────────────
for color_idx, (current_color, point_list) in enumerate(point_name_pairing):
if not point_list:
continue
pipette_20ul.pick_up_tip()
max_aspirate = int(18 // POINT_SIZE) * POINT_SIZE
qty_to_aspirate = min(len(point_list) * POINT_SIZE, max_aspirate)
update_volume_remaining(current_color, qty_to_aspirate)
pipette_20ul.aspirate(qty_to_aspirate, location_of_color(current_color))
# FIX: renombrado índice interno 'pt_idx' para no pisar 'color_idx'
for pt_idx in range(len(point_list)):
x, y = point_list[pt_idx]
adjusted_location = center_location.move(types.Point(x, y, 0))
dispense_and_jog(pipette_20ul, POINT_SIZE, adjusted_location)
remaining = point_list[pt_idx + 1:]
if pipette_20ul.current_volume == 0 and remaining:
qty_to_aspirate = min(len(remaining) * POINT_SIZE, max_aspirate)
update_volume_remaining(current_color, qty_to_aspirate)
pipette_20ul.aspirate(qty_to_aspirate, location_of_color(current_color))
pipette_20ul.drop_tip()
The script implements a volume-tracking helper (update_volume_remaining) that advances to the next row of the PCR strip when a well exceeds 250 µL of use, preventing over-aspiration. The dispense_and_jog function moves 2 mm above the agar surface before dispensing and retracts afterward, minimizing cross-contamination between dots. Coordinates are relative to the center of the agar plate (agar_plate['A1'].top()) and were generated directly from the opentrons-art GUI export.
AI use declaration: The Python script (Diseño_Art.py) was reviewed and debugged with assistance from an AI language model (Claude, Anthropic). Two bugs were identified and corrected: (1) the absolute z-coordinate offset in dispense_and_jog was replaced with a relative types.Point(z=2) offset; (2) the loop variable color_idx was renamed pt_idx inside the inner point loop to avoid shadowing the outer enumeration variable. The pixel art design coordinates were generated using the opentrons-art.rcdonovan.com web interface without AI assistance.
Published Paper — ACCS System
The paper reviewed is "Open-Source Cell Culture Automation System with Integrated Cell Counting for Passaging Microplate Cultures" (Courville et al., 2025, PNAS Nexus). It describes the Automated Cell Culture Divider (ACCS) -- an Opentrons OT-2 system with a custom-integrated cell count imager (CCI) that measures cell concentration in real time to adjust seeding volumes per well.
Precision: CV less than 11% well-to-well, vs. manual estimation which is highly variable.
Imaging performance: 92% usable imaging sites (OpenCell 3D fluorescence) vs. 52% manual.
Efficiency: 61% reduction in researcher intervention time per run.
Open-source: All hardware and Python software released under open-source licenses.
ACCS Paper — Extended Critique
The ACCS system (Courville et al., 2025, PNAS Nexus) demonstrates significant advances in open-source lab automation, but a committed reader must interrogate both its methodological assumptions and the limits of its transferability.
Transferability to non-mammalian systems. The ACCS system was validated exclusively on adherent mammalian cell lines. Bacterial cultures — including E. coli K-12 and Halomonas elongata as used in Füzi Poiesis — have fundamentally different growth kinetics (generation time ~20 min vs. 24+ hours), do not require attachment surface monitoring, and measure density by optical methods rather than cell counting. The CV and imaging benchmarks reported by Courville et al. cannot be assumed to transfer to bacterial microplate cultures without re-validation.
Closed-loop feedback limitation. The ACCS system adjusts seeding volumes based on cell density measured at the time of passaging — a single-point measurement. It does not implement continuous monitoring or adaptive control during the growth phase. For a Lotka-Volterra-based consortium like Füzi Poiesis, where population dynamics are governed by differential equations with time-varying metabolite concentrations, a single-point density readout is insufficient to parameterize the ODE system in real time. True closed-loop automation would require in-line metabolite sensing (SRP, H₂S, AHL) integrated with the OT-2 pipetting logic.
Statistical scope. The n reported for precision benchmarks is not specified in the abstract. CV below 11% is promising but the confidence interval around this estimate depends on the number of replicate runs, which is critical for evaluating whether the precision advantage over manual is statistically significant across different operators and cell types.
For the Nash Automaton protocol — the Opentrons-based automated selection system designed for Füzi Poiesis — the ACCS architecture would need to be extended in three directions: (1) replacing the cell count imager (CCI) with a turbidimetry module or OD600 reader compatible with bacterial microcultures; (2) integrating a fluorescence module to read quorum signal (AHL-linked GFP reporter in Strain C) as a proxy for consortium population ratio; and (3) replacing single-point density measurement with multi-timepoint sampling to fit Monod growth parameters in real time and feed them back into the Lotka-Volterra selection logic. The open-source Python codebase released by Courville et al. provides the OT-2 control infrastructure on which these extensions would be built.
The Nash Automaton
The automation design for the project was the Nash Automaton -- a robotic protocol that subjects the consortium to iterative metabolic tests under automated artificial selection, executing a Minimax algorithm to select the variant that best withstands worst-case environmental stress from Lake Budi.
from opentrons import protocol_api
metadata = {
'apiLevel': '2.13',
'protocolName': 'Nash Automaton: Minimax Stress Matrix',
'author': 'Nicolas Escobar Fierro -- HTGAA 2026',
'description': 'Automated distribution of stressors for consortium selection.'
}
def run(protocol: protocol_api.ProtocolContext):
benthic_plate = protocol.load_labware('corning_96_wellplate_360ul_flat', '1')
stressors_res = protocol.load_labware('nest_12_reservoir_15ml', '2')
inoculum_res = protocol.load_labware('nest_12_reservoir_15ml', '3')
tiprack = protocol.load_labware('opentrons_96_tiprack_300ul', '4')
p300 = protocol.load_instrument('p300_single_gen2', 'right', tip_racks=[tiprack])
h2s_toxin = stressors_res.wells()[0]
master_inoculum = inoculum_res.wells()[0]
# H2S gradient: 10 uL start, +2.5 uL per well (max 247.5 uL, safe for 360 uL well)
current_vol = 10
vol_increment = 2.5
p300.pick_up_tip()
for well in benthic_plate.wells():
p300.transfer(current_vol, h2s_toxin, well,
mix_after=(2, 20), new_tip='never')
current_vol += vol_increment
p300.drop_tip()
p300.pick_up_tip()
for well in benthic_plate.wells():
p300.transfer(25, master_inoculum, well, new_tip='never')
p300.drop_tip()
protocol.comment("Nash Automaton complete.")
The MazF/MazE kill switch was replaced in Fuzi Poiesis by topological biocontainment via the three-strain auxotrophic ring. The AND-gate inputs were updated from skatole/H2S to AHL quorum signal and soluble reactive phosphorus. The osmotic acclimation and co-culture inoculation logic remain directly applicable to Aim 2.
AI use declaration: For the development of the Opentrons script, the Gemini language model (Google) was used as a technical review assistant, optimizing stress gradients and ensuring volumetric safety of the protocol.
Nash Automaton — Executable Protocol
The Nash Automaton was the automation design concept for Füzi Poiesis at this stage of the project — a robotic protocol implementing iterative metabolic selection using Opentrons OT-2 as the physical execution layer. The mathematical framework draws from Lotka-Volterra population dynamics and Minimax decision theory. Note: as the project evolved toward topological biocontainment via auxotrophic coupling, the Nash Automaton's role shifted from an active control mechanism to a characterization tool for Aim 2 parameter estimation.
- Step 1 · Initialization (t = 0) — Load three strains (Strain A, B, C) into a 96-well microplate at equal starting densities (OD₆₀₀ ≈ 0.05 each) in minimal medium supplemented with the auxotrophic amino acids at defined concentrations: L-leucine (Strain A supply, 50 μM), L-tryptophan (Strain B supply, 50 μM), L-histidine (Strain C supply, 50 μM). Total volume per well: 200 μL. Plate layout: 8 replicates per condition, 4 amino acid concentration conditions (0×, 0.5×, 1×, 2× baseline), 3 monoculture controls.
- Step 2 · Growth phase (t = 0 to 4 h) — Incubate at 37°C with orbital shaking at 200 rpm. No OT-2 action required during this phase. OD₆₀₀ is read by plate reader at t = 0, 1, 2, 3, 4 h to parameterize Monod growth rates (μ_max) and carrying capacity (K) for each strain under each amino acid concentration condition.
- Step 2 · Density readout — At t = 4 h, OT-2 transfers 20 μL from each well to a flat-bottom OD measurement plate (P300 multi-channel pipette, 96-well format). OD₆₀₀ is read and values transmitted to the Python control script.
- Step 3 · Lotka-Volterra parameterization — The Python control script fits the six-equation ODE system (dN_i/dt = μ_max,i · S_j/(K_i + S_j) · N_i − D·N_i) to the time-series OD data using scipy.optimize.curve_fit. The fitted μ_max and K values are used to compute the Jacobian eigenvalue spectrum and verify that the current amino acid concentrations maintain the system at the stable interior fixed point.
- Step 4 · Minimax selection — The control script applies the Nash Minimax criterion: identify the amino acid concentration set that minimizes the maximum deviation of each strain from its target equilibrium density (n* ≈ 0.629 in dimensionless units). This is equivalent to finding the strategy that is most robust to perturbation — the Nash equilibrium of the three-player consortium game.
- Step 5 · Passaging (t = 4 h) — OT-2 prepares fresh medium with the Minimax-selected amino acid concentrations. Using P300 multi-channel pipette: aspirate 180 μL from each well, discard, add 180 μL fresh medium at Minimax concentrations + 20 μL culture (1:10 dilution). This maintains the consortium at log-phase growth while updating metabolite supply to the optimal strategy.
- Step 6 · Iteration — Steps 2–5 repeat for 6 passaging cycles (24 h total), producing a time series of Lotka-Volterra parameters under automated artificial selection. Final readout: the amino acid concentrations and OD₆₀₀ ratios at which the three-strain consortium maintains stable coexistence closest to the predicted interior fixed point.
Opentrons OT-2 · P300 multi-channel GEN2 pipette · Corning 96-well flat-bottom microplate · Opentrons 96-well aluminum block at 37°C · 12-channel reservoir for media preparation · Opentrons 300 μL tip rack (×4). Python packages: opentrons API v2, scipy, numpy, pandas. Script execution: Jupyter notebook running on OT-2 onboard computer via SSH, with plate reader data imported via CSV after each OD measurement cycle.
The Nash Automaton was designed at this stage of Füzi Poiesis as an active control mechanism — the robot would continuously adjust the biochemical environment to maintain the Nash equilibrium of the three-strain game. As the project architecture matured, this role was re-scoped: topological biocontainment via auxotrophic coupling encodes stability structurally into the consortium, without requiring external robotic intervention. The Nash Automaton's role in the final Füzi Poiesis design is therefore as a Aim 2 characterization tool — used to measure the Monod kinetic parameters needed to calibrate the ODE model for native Lake Budi strains — rather than as a deployment control system.
Connecting to the Node
This week was the first where the course stopped feeling abstract and started feeling like a community. The SynBio USFQ Node brought together students from across South America — Argentina, Chile, México — and for the first time I was sharing a virtual space with people who were navigating the same course from the same side of the world, with the same timezone problems, the same access constraints, and the same excitement.
What I didn't expect was the range of people. I'm 21. Some of the others in the node are senior researchers, founders of biotech companies, people who have already built things — real things, not student projects. Sitting in the same call as someone who runs a biotech firm in Buenos Aires or Mexico City while I'm still figuring out what direction to take is a strange and clarifying experience. Not intimidating in the way I feared. More like a useful collision.
The age gap cuts both ways. They have experience I don't have — industry knowledge, real failure, institutional context. I have something too, maybe: fewer fixed assumptions about what's possible, less attachment to how things have been done. The most interesting conversations this week weren't about protocols or papers. They were about why each person is here — what problem they're actually trying to solve. Everyone had a different answer. Nobody's answer was wrong.
Temuco doesn't appear on many synthetic biology maps. La Frontera isn't a research hub by any conventional measure. Being here — designing pixel art for a robot I'll never touch, writing protocols for a lab I'll never walk into, submitting forms across a twelve-hour timezone difference — has a specific texture. There's something clarifying about doing serious work from a place that doesn't expect it of you. The node made that feel less like a limitation and more like a position.
Most of the people I met this week have been working in biology longer than I've been thinking about it seriously. That used to feel like a disadvantage. This week it started to feel like information — a data point about how long it takes to build something worth building, and a reason to start now rather than later.
The Genesis of Fuzi Poiesis
This week's assignment required presenting three different concept slides for what our project could be. I submitted one slide with three distinct levels of complexity and ambition -- from the most grounded to the most epic. None of these concepts survived exactly into the final design, but all three fed the thinking that became Fuzi Poiesis.
The Scaffolding: Local hardware, living software. Pumice/Bokashi acts as a low-entropy skeleton. Within its micropores resides the K-Core -- a minimal consortium of native bacteria that operate as an obligatory metabolic symphony, transforming the physical support into a biological processor.
Core Pillars: Topological Resilience (strengthening key nodes to stabilize the ecosystem through cascading effects), Metabolic Bricolage (syntrophic engineering via cross-auxotrophies), and Entropy Sequestration (converting H2S/Nitrogen pollutants into useful biomass).
What survived into Fuzi Poiesis: The Bokashi del Budi scaffold, the cross-auxotrophic coupling, and the syntrophic engineering logic are all present in the final design.
Core idea: Eutrophication in Lake Budi acts as metabolic amnesia, collapsing biodiversity (Shannon Entropy). Inspired by Kintsugi -- the Japanese art of repairing broken pottery with gold -- we repair the broken biogeochemical network not with foreign species, but by patching native microorganisms with synthetic biology, creating a resilient hybrid ecosystem.
Control Logic: AND gate (H2S AND pathogens exceed threshold) activates the remediation operon. MazF/MazE kill switch for biocontainment.
What survived: The AND-gate logic (inputs later changed to AHL + SRP), the Shannon entropy framing of ecosystem collapse, and the name "Kintsugi Inoculum" -- which later became "Fuzi Poiesis" after incorporating Mapudungun and Maturana's autopoiesis concept.
Core idea: Biogeochemical entropy (cyanobacterial bloom) leads to system collapse (anoxia), while the player (Nash Automaton) seeks bioremediation. The game is won when equilibrium is reached and the lake's metabolism is regulated. Non-zero-sum game: both the ecosystem and the community win.
Players: Nash Automaton (Opentrons + Lotka-Volterra + Minimax) as feedback loop control; Cyanobacterial Bloom as the opponent (exponential growth and positive feedback of collapse); Lake Budi as referee.
What survived: The Lotka-Volterra population dynamics framework, the Nash equilibrium framing, and the Minimax automated selection logic all appear in the final Fuzi Poiesis ODE model and Aim 2 experimental design.
None of these three concepts was chosen -- and all three were. The Bricolage Inoculum provided the physical scaffold (Bokashi del Budi). The Memory of Gold provided the AND-gate circuit logic and the name lineage (Kintsugi Inoculum - Fuzi Poiesis). The Gambit of Redemption provided the mathematical framework (Lotka-Volterra, Nash equilibrium, Lyapunov stability). Fuzi Poiesis is the synthesis of all three, stripped of the poetic framing and rebuilt on rigorous mathematical foundations.