Category: Essays

Essays on engineering leadership, agents and physical AI.

  • Low Context, High Stakes: Leading Engineering Across Four Cultures in the Age of AI

    I lead engineering from Austin, and most weeks the work runs through four countries: the United States, Poland, Ireland and India. The same sentence lands differently in each. In Austin, “this is great” is a polite acknowledgement. In Kraków, nie jest źle, “not bad”, can be genuine praise. In Ireland, “that’s grand” can mean anything from “excellent” to “we have a problem”. In India, a “yes” in a meeting often means “I heard you”, not “I agree”. Most of the friction in distributed engineering is not technical. It is context.

    This essay is about that context: what the research says about how these four cultures differ, what the numbers do and do not mean, and why AI makes this old leadership problem both easier and more dangerous.

    Two ways to say the same thing

    In 1976 the anthropologist Edward T. Hall split cultures into high-context and low-context. In a low-context culture, the message is the words: say it explicitly, repeat it, put it in writing, and the responsibility for being understood sits with the sender. In a high-context culture, much of the meaning lives around the words, in the relationship, the history and what is left unsaid, and the listener is expected to read between the lines.

    Erin Meyer’s The Culture Map turned that idea into a scale managers can use. It puts the United States at the extreme low-context end, and India firmly on the high-context side: communication there is layered and relational, and a lot is said by what is not said. Meyer’s published summaries do not place Poland or Ireland by name, so for those two I rely on my own experience. Polish engineering culture is far lower-context than India’s but leans more on relationships and reading the room than the American default. Ireland shares the English-speaking, low-context default on paper, then softens it with understatement, humour and a reluctance to say the hard thing too plainly.

    The twist is feedback. Meyer separates how explicitly people communicate from how directly they criticise. She puts most European cultures on the direct side of negative feedback and Americans and the British in the middle. That matches what I see, with one wrinkle: Poland is the outlier in my four. A Polish engineer will tell you in a code review that your design will not scale, without the cushioning. An American manager wraps the same message in two compliments. An Irish colleague might say it is “an interesting approach”. An Indian colleague might not say it in the meeting at all, and raise it later, one to one. The same comment can read as normal in Kraków and as harsh everywhere else, and a concern that was voiced in Ireland or India can go completely unheard in Austin.

    What the data says

    The most widely used dataset for comparing national cultures comes from Geert Hofstede, whose original research in the late 1960s and 1970s was built on surveys of IBM employees in dozens of countries. It is maintained today by The Culture Factor, the firm behind the Culture Compass. Hofstede’s 6-D model scores each country from 0 to 100 on six dimensions. Here is how the four compare:

    Hofstede 6-D scores for the United States, Poland, Ireland and India. Power distance: United States 40, Poland 68, Ireland 28, India 77; Individualism: United States 60, Poland 47, Ireland 58, India 24; Achievement and success: United States 62, Poland 64, Ireland 68, India 56; Uncertainty avoidance: United States 46, Poland 93, Ireland 35, India 40; Long-term orientation: United States 50, Poland 49, Ireland 51, India 51; Indulgence: United States 68, Poland 29, Ireland 65, India 26.United StatesPolandIrelandIndia0255075100Power distancespread 49United States · Power distance: 4040Poland · Power distance: 6868Ireland · Power distance: 2828India · Power distance: 7777Individualismspread 36United States · Individualism: 6060Poland · Individualism: 4747Ireland · Individualism: 5858India · Individualism: 2424Achievement and successspread 12United States · Achievement and success: 6262Poland · Achievement and success: 6464Ireland · Achievement and success: 6868India · Achievement and success: 5656Uncertainty avoidancespread 58United States · Uncertainty avoidance: 4646Poland · Uncertainty avoidance: 9393Ireland · Uncertainty avoidance: 3535India · Uncertainty avoidance: 4040Long-term orientationspread 2United States · Long-term orientation: 5050Poland · Long-term orientation: 4949Ireland · Long-term orientation: 5151India · Long-term orientation: 5151Indulgencespread 42United States · Indulgence: 6868Poland · Indulgence: 2929Ireland · Indulgence: 6565India · Indulgence: 2626
    Hofstede 6-D scores for the US, Poland, Ireland and India. Source: The Culture Factor country comparison
    DimensionUSPolandIrelandIndia
    Power distance40682877
    Individualism60475824
    Achievement and success62646856
    Uncertainty avoidance46933540
    Long-term orientation50495151
    Indulgence68296526
    Hofstede 6-D model scores as published by The Culture Factor, October 2026. Scale 0 to 100.

    The four cultures split along two lines, and agree on two things.

    Power distance: two flat cultures and two hierarchical ones

    Ireland (28) and the US (40) expect managers to be accessible and to be challenged. Poland (68) and India (77) accept hierarchy as natural: the boss is expected to decide, and contradicting a senior leader in front of the room is costly. India’s score comes with a clear expectation of a directive, protective leader and, in Hofstede’s words, negative feedback that is rarely passed upward. Put an Irish or American executive in front of a Polish or Indian team, ask “any concerns?”, hear nothing, and you have the most dangerous meeting in distributed engineering: everyone leaves believing the plan is sound, and the people closest to the problem never said so.

    Uncertainty avoidance: Poland alone

    This is the largest spread on the chart, and it is one country against three. Poland scores 93: a strong need for rules, precision and plans, and a healthy suspicion of untested ideas. Ireland (35), India (40) and the US (46) are comfortable with ambiguity. American product teams treat it as freedom; Irish teams as room for ideas; Indian teams are famously good at what people there call “adjusting”, finding a way around a constraint that looked fixed. A Polish team that asks fifteen clarifying questions is not being difficult; it is doing the risk analysis the plan skipped. An Indian team that quietly adapts the plan to make it work is solving the problem, and also, sometimes, hiding it.

    Indulgence: optimism and restraint

    The US (68) and Ireland (65) score as indulgent cultures, optimistic and comfortable with enthusiasm. Poland (29) and India (26) score as restrained, cautious and wary of overclaiming. This shows up in tone and in status reports: American and Irish updates run green until they are suddenly red, while Polish and Indian ones run amber long after the risk is under control. Calibrate before you escalate.

    Individualism: India’s team-first culture

    The US (60) and Ireland (58) are individualist, Poland (47) sits in the middle, and India (24) is the most group-oriented of the four. Loyalty runs to the team and the manager, relationships shape decisions, and being singled out in public, for praise or for blame, can be uncomfortable. Recognition that lands well in Austin, one name on a slide, can land badly in India, where the team did the work and expects to be thanked as a team.

    What all four share

    Achievement and success (56 to 68) and long-term orientation (49 to 51) are close across all four; on long-term orientation the four scores sit within two points of each other. All four cultures are driven, competitive and pragmatic. People in every one of these offices want to win and want to do the work properly. That shared drive is the foundation, and it is why these teams work so well once the context problems are solved.

    The twin trap

    On paper, the US and Ireland look like twins: within twelve points of each other on every dimension. That is exactly what makes them easy to get wrong. Shared language hides real differences: Ireland is flatter than the US, more comfortable with ambiguity, and far more fond of understatement. An American who takes “it should be grand” at face value, or an Irish engineer who reads American enthusiasm as a commitment, is making the same mistake from opposite ends.

    Setting context: what these numbers are, and are not

    Country scores are useful and easy to misuse, so a few caveats before anyone builds a team on them.

    • They describe the middle of a distribution, not your colleague. A national score is an average of survey answers. Treating it as a description of an individual is the ecological fallacy, and it turns a research tool into a stereotype.
    • Some countries are many cultures. India’s scores average across more than a billion people, dozens of languages and very different regions and generations. A software engineer in one of its tech hubs may have more in common with a colleague in Kraków than with the national average.
    • Your team is not the national average. Engineering has a culture of its own, and it is lower-context and more egalitarian than most of the countries it works in.
    • The numbers move. Scores are periodically recalibrated with newer data. In its 2023 update, The Culture Factor cut the US individualism score from 91, the figure most textbooks still quote, to 60. Check the current scores before you quote old ones.
    • Use them as hypotheses. When a team keeps clashing in the same place, the dimensions give you a vocabulary for why, so the conversation can be about the gap instead of about the people.

    That last point is why I like the Culture Compass more than the country charts. It is a 42-question assessment of your own preferences. You choose your role, such as manager, colleague or negotiator, and up to three countries per report, and it shows the three dimensions where you differ most from each one. A manager working across all four of these cultures needs two runs. What matters on a distributed team is not any country’s score; it is the gap between a particular manager and the people they lead. An American leader with low uncertainty avoidance leading a team in Kraków, or an Irish leader with very low power distance leading a team in India, should know that before the first planning cycle, not after the third missed expectation.

    Where AI changes the equation

    A large language model is the most low-context colleague you will ever have. It knows nothing about your project that you did not write down. That makes AI an unexpected ally for distributed teams: the discipline it demands, explicit goals, written constraints, a clear definition of done, is exactly the discipline cross-cultural teams have always needed. I have argued before that context is the real work; teams that learn to write good context for agents write better context for each other.

    Where it helps

    • Intent, written down. A one-page statement of the goal, the constraints and what must not happen serves an agent, an engineer in Kraków, a team in India and a product manager in Austin equally well. High uncertainty-avoidance teams get the clarity they need; high-context teams get the background nobody thought to say out loud.
    • Handoffs across the time zones. Austin is about seven hours behind Kraków, six behind Ireland and ten and a half to eleven and a half behind India, depending on the season. Austin and India barely overlap at all; Europe is the bridge, sharing working hours with both. AI summaries of each region’s threads, decisions and open questions make a three-hop, follow-the-sun handoff workable, and let the overlap hours be spent on conversation instead of status updates.
    • Translating register, not just language. Before sending difficult feedback, ask a model how it is likely to land with a reader from the other culture. Use it to decode the message, not to sanitise it: what does “that’s grand” or a quiet “yes” actually mean here?
    • Lowering the cost of dissent. Asynchronous design reviews, written pre-mortems and AI-collected risk lists give people a way to say “this will not work” without contradicting a senior leader in a live meeting. In the two high power-distance cultures, that is often the only way the warning arrives in time.

    Where it hurts

    • Flattening. Models default to an upbeat, hedged, American corporate register. Run a Polish engineer’s blunt and accurate assessment through one and the signal gets softened away. Run Irish understatement or Indian politeness through one and a real concern becomes indistinguishable from agreement.
    • Stripping the context. High-context communication depends on relationship and subtext. A summary keeps the words and loses everything around them, which is exactly the part that mattered.
    • False fluency. AI makes everyone’s English polished. Polished writing is not agreement, and it can hide the very disagreement you need to hear.
    • Outsourcing the relationship. Summaries are not trust. The relational part of collaboration still happens in person and over time, and in group-oriented, high-context cultures it matters even more. Keep putting people on planes.

    A short playbook

    1. Have every manager on a multi-country team take the Culture Compass against the countries they work with, and discuss the gaps openly as a team.
    2. Write intent for every significant piece of work. If an agent could not act on it, neither can a team ten hours away.
    3. Never treat silence as agreement. Ask for risks in writing, before the meeting, by name, and make it safe to send them one to one.
    4. Calibrate feedback in every direction. Teach Americans that Polish directness is not hostility, and teach everyone that Irish understatement and Indian politeness can carry a serious warning.
    5. Recognise teams as well as individuals, especially where the culture is group-oriented.
    6. Design handoffs around the bridge: let the European offices connect the American and Indian days, and use AI summaries to carry context across each hop.
    7. Use AI to summarise, translate and decode, and never to rewrite someone’s judgement into something more comfortable.

    The goal is not to make Poland, Ireland or India more like the United States, or the other way round. It is to make the implicit explicit, so every team can be itself and still build the same thing. AI makes writing context cheap. It does not make trust cheap, and leaders still have to earn that one the old way.

    Sources

  • Building LOCI Companion, Part 1: A Personal AI Assistant That Remembers What You See

    Building LOCI Companion, Part 1: A Personal AI Assistant That Remembers What You See

    LOCI Companion is a personal AI assistant with a memory for what you have seen. It is a small camera worn on the chest that remembers what it saw, where and when, so you can ask about it later: where did I leave my keys, what was on that whiteboard, what was the name of the wine at dinner. I have a working demo on my desk. This series is me building the rest of it in public.

    This is Part 1 of Building LOCI Companion. It covers the idea, the hardware I am using today and where the project stands. It also opens up the architecture and LOCI-DB, the memory underneath, with diagrams and code you can run. Later parts go deeper into the firmware, battery life and the first people to wear it.

    See it work

    Before the idea and the architecture, here is the current prototype doing the one thing it exists to do. It is twenty-two seconds, unedited, filmed on my desk.

    LOCI Companion prototype · ESP32-P4, camera and speaker · sound on

    Me, holding the button: Where is the refrigerator?

    LOCI Companion: Your refrigerator was last seen on the right, in the middle area. That was one day ago, at 4:57 PM. That was before I restarted. It’s to the right of the remote.

    That answer is short, but almost every part of the system is in it. This is what happens between the question and the reply:

    1. A day earlier, it saw the refrigerator. While it ran, the board sent a camera frame to the host about twice a second. The detector found a refrigerator and a remote, and each sighting was stored in LOCI-DB as a memory: what it was, where in view it sat, and exactly when.
    2. Then it was switched off. The host process restarted. The memory did not disappear: the assistant saves what it has seen to disk and reloads it on start. The phrase “That was before I restarted” is the assistant being honest that this memory comes from a previous session, not from what it can see right now.
    3. I press the button and ask. The board records my voice and sends the audio to the host, where a local speech model (faster-whisper) turns it into text. Nothing goes to a cloud service.
    4. The question becomes a memory lookup, not a guess. “Refrigerator” is matched to the label the detector uses, and LOCI-DB returns the most recent sightings of it, newest first, with their position and timestamp.
    5. The answer is built from facts. The position becomes words (“on the right, in the middle area”), the timestamp becomes “one day ago, at 4:57 PM”, and the nearest other object remembered at the time becomes a landmark: “to the right of the remote”. No language model is asked to invent the answer; every phrase traces back to a stored observation.
    6. It speaks. The host turns the sentence into audio and the board plays it from its speaker. In this take the answer starts about three and a half seconds after I stop talking, slower than the 1.3 seconds I have measured at best. Closing that gap is on the list.

    Two honest caveats. “On the right, in the middle area” describes where the refrigerator was in the camera’s view, not in the room: the pendant has no depth sensor, so it cannot yet say “in the kitchen, by the window”. The first prototype, with its depth camera, could; more on that below. And the detector only knows about eighty common object types, so it can find a refrigerator or a cup today, but not your keys. Both are solvable, and both are later parts of this series.

    Where this is going: v0.6 “Visor”

    What you just watched is a development board on a desk. This is what I am designing it to become: the same electronics and the same fit, redesigned so it looks like something you would actually want to wear. These are renders, not photos. The enclosure has been fit-checked against the CAD model of the battery module, but it has not been printed yet.

    Render of LOCI Companion v0.6: a white rounded-square pendant on a black cord, with a smoked glass visor across the top covering the camera lens, speaker grille and recording light, and a single round button below
    The target design, v0.6 “Visor”: 84 × 85 × 26 mm, about 136 g, worn on a cord. Render.

    Inside it is exactly what is on my desk today: the Waveshare ESP32-P4 board, its camera and speaker, and the NULLLAB PM11 battery module. Everything that changed is on the outside, and every change is there for a reason.

    Side-by-side renders of v0.5, a plain box with an exposed lens, slotted speaker grille and square button, and v0.6, with the lens and speaker behind a dark glass visor and a round button
    Same parts inside, before and after: v0.5 on the left, v0.6 on the right.
    • One piece of glass. A smoked acrylic visor runs across the top. The lens, the speaker and the recording light all sit behind it, so the front reads as one calm surface instead of a lens, a grille and a row of holes.
    • Hidden until lit, and impossible to miss when it is. The recording light glows through the glass, and the battery level glows through a 0.45 mm skin in the shell. No light, no holes. This matters more than it looks: the hardest problem with a wearable camera is the people around you, and a light they can clearly see while it is recording is the most basic courtesy the device can offer.
    • One button. A round, dished button you can find without looking, on a printed flexure that takes about 2 N to press. Hold to ask, release to hear the answer: the same interaction as in the video.
    • Looks thinner than it is. An 8 mm soft front edge and a dark, tapered base make the 26 mm body read closer to 20 mm when it hangs on you.
    • Fewer holes. The board’s BOOT and RESET buttons are gone from the face, there is a single microphone pinhole, and the ports sit in clean stadium-shaped pockets.
    • A softer shape. Continuous-curvature corners, the same squircle as an app icon, instead of a rounded box.
    Three renders of the v0.6 pendant in dark navy, white and pale green
    Three finishes: Midnight, Cloud and Sage.

    It is designed to be made without a factory. The body is MJF nylon, dyed, or SLA resin with a matte paint; ordinary FDM printing works but shows layer lines. The visor is 2 mm smoked cast acrylic, laser-cut from a DXF. The bezel around the lens is silk-silver resin for now and a CNC-machined aluminium ring later, and the base is printed in black, because that dark band is what makes the whole thing look like it floats.

    Exploded render showing the dark base, the electronics with the battery module, the white shell and the glass visor with its bezel
    How it goes together: base, electronics (the real PM11 battery model), shell, then glass and bezel.

    Getting from the board in the video to this is the work of the next few parts of the series: printing and fitting the enclosure, measuring real battery life, and moving the recording light and privacy controls from a design choice into firmware. The full v0.6 design sheet is here.

    The idea: an assistant that was there

    Today’s AI assistants know a lot about the world and almost nothing about your day. They can explain quantum field theory but cannot tell you where you put your passport, which slide your colleague showed on Tuesday, or whether the shelf in the garage was already empty last week. Everything they know about your life is what you remember to type in.

    LOCI Companion is my attempt to close that gap. It does three things:

    1. Sees. A small camera at chest height captures what is in front of you, when you want it to.
    2. Remembers. What it saw is stored with where and when it saw it, so the assistant builds up a memory of your physical world over time instead of starting from zero every conversation.
    3. Answers. You ask in plain language, by voice, and it answers from that memory. When something has changed in a place you care about, it can tell you.

    The everyday version is mundane on purpose: finding things, recalling things, noticing things. Where I parked. What the label on the medicine box said. Who was at the table. The same memory is also powerful for people who need it most: someone who is blind or has low vision, or someone living with memory loss, gets far more from an assistant that remembers than from one that only describes the current moment. I want both to work, and I will test with both.

    Why the memory matters more than the camera

    The camera is the easy part. The hard part, and the part I care about most, is the memory underneath it. That is LOCI-DB, an open-source spatial memory I have been building for robots, drones and world models. It stores each observation with its position in space and its moment in time, indexes them together on a four-dimensional Hilbert curve, and returns a novelty score that says how different the current view is from anything seen before at that place.

    Those two properties are what make it an assistant rather than a camera. Indexing by place and time means a question like “where did I last see my keys” is a lookup, not a search through hours of footage. Novelty means the assistant can stay quiet most of the time and speak up only when something actually changed. An assistant that talks less and says more is the whole product.

    A robot and a person wearing a pendant have the same underlying problem: they move through a world, see it from one point of view, and need to remember what they saw. LOCI Companion is the first place I am putting that memory on a human.

    How the pieces fit

    The pendant is a thin client. It does the things that have to happen on your body: look, listen, speak, and keep working when the network does not. Everything heavy runs on a host I own, which today is a laptop and could as easily be a Raspberry Pi in a cupboard. The two talk HTTPS over one keep-alive connection, either on the home network or through a Cloudflare Tunnel when I am out.

    LOCI Companion system: the pendant streams camera frames and voice questions to a host, which runs detection, LOCI-DB memory, speech recognition and speech synthesis, and sends the spoken answer back. When the host is unreachable the pendant stores frames on its microSD card and answers from cached phrases. ON THE NECK · ESP32-P4 Camera1280×960 JPEG, about 2 fps Microphone + buttonpush to talk, 16 kHz audio microSD cardbacklog, cached answers On-device speechESP-SR MultiNet7, no cloud Speakerthe answer, spoken OFFLINE PATH FRAMES QUESTION AUDIO PCM ANSWER HTTPS + DEVICE TOKEN LAN OR CLOUDFLARE TUNNEL HOST · LAPTOP, PI OR SERVER Object detectionYOLOv8n: what, and where in frame Speech to textfaster-whisper, local LOCI-DBwhat · where · when+ novelty, trajectories Answer in words Text to speech16 kHz PCM back to the board STORE ASK Nothing heavy runs on the board. When the host is gone, frames go to the card and upload later with their original timestamps.
    Figure 1 · The pendant sees and speaks; the host detects, remembers and answers

    A frame goes up roughly twice a second. The host runs object detection on it, and every detection becomes a memory in LOCI-DB: a label, a position, a time and a confidence. When I hold the button and ask a question, the audio goes up the same pipe, is transcribed locally, answered from the memory, turned into speech and played from the board’s speaker.

    The part I am proudest of is the offline path. If the host disappears, the pendant keeps capturing to its microSD card and uploads the backlog later with the original timestamps, so the memory has no holes. It also caches a spoken answer per remembered object, and an on-device speech recogniser (Espressif’s MultiNet7, no wake word, no cloud) can match “where is my cup” and play the cached answer with no host at all.

    Inside LOCI-DB

    Most AI memory today is a vector database: you turn things into embeddings and find the ones most similar to a question. That covers what. A wearable also needs where and when, and it needs all three in a single query. “Where did I leave my cup” is a similarity question with a place answer. “What was on the table this morning” is a place question with a time window. Bolting coordinates onto a vector store as ordinary filters works for a demo and falls over as the memory grows. LOCI-DB makes space and time part of the index.

    A memory is what, where and when

    The unit of memory is a WorldState: an embedding vector for what was seen, an x, y, z position, a timestamp in milliseconds, a scene_id that groups observations of the same thing, a confidence and free-form metadata. States in the same scene are linked to the one before them, so the database can replay how something moved over time.

    The Hilbert curve: one number for space and time

    The core trick is a space-filling curve. A Hilbert curve visits every cell of a grid in a single continuous line, and it has a useful property: cells that are close together in space are mostly close together along the line. LOCI-DB encodes each memory’s (x, y, z, t) onto a four-dimensional Hilbert curve, so every memory gets an integer address. It does this at three resolutions (16, 256 and 4,096 bins per axis) so both coarse and fine questions stay cheap.

    An 8 by 8 grid traversed by a Hilbert curve. A query box covering 9 cells maps to 3 short runs of the curve index.SPACE (2D SLICE OF 4D)063QUERY BOXTHE SAME CELLS ON THE CURVE0639 cells in the box become3 runs of the curve index:6–11, 53–54, 57Nearby in space stays nearby on thecurve, so a box is a short list ofintegers to match instead of ageometry scan over every memory.
    Figure 2 · A 2D slice of the idea: a box in space becomes a few runs of integers

    A question about a place then becomes a short list of curve addresses to match, an integer filter the storage engine is very good at, instead of a geometric scan over every memory. The bucket list only narrows the search. Exact coordinate, time and confidence ranges are applied in the same filter before the nearest neighbours are picked, and an exact geometric check at the end means nothing just inside the edge of the box is missed.

    LOCI-DB write and read paths. A memory is encoded on a 4D Hilbert curve and stored in a raw collection; old epochs consolidate into a summary collection. A query turns a place and time window into Hilbert bucket IDs and exact ranges, searches both collections, checks geometry exactly and re-ranks by recency. WRITE: REMEMBER WorldStatevector = whatx, y, z = where · t = when 4D Hilbert encode(x, y, z, t) → one intat 3 resolutions loci_dataraw memories,causally linked loci_summaryold epochs foldedinto gist CONSOLIDATE AS IT AGES READ: “WHERE DID I LEAVE MY CUP?” 1 · Questionvector + place box + time window 2 · Bucket coverbox → short list of Hilbert IDs 3 · Filtered searchIDs + exact ranges, then top-k 4 · Both collectionsraw + summary, merged 5 · Exact checkno misses at box edges 6 · Recency re-ranksimilarity × time decay “Your cup was last seen in the middle of the table, 3 hours ago. It’s to the left of the scissors.”
    Figure 3 · How LOCI-DB stores a memory and answers a question

    Memory that ages like memory

    A pendant that remembers everything forever is a storage problem and a privacy problem. LOCI-DB keeps two collections: raw memories, and summaries. Time is cut into logical epochs, and as epochs get old their raw states are folded into per-scene summaries and deleted. Recent memory stays sharp, old memory becomes gist, and storage stays bounded however long the device runs. Results are also re-ranked by recency with an exponential decay that halves every hour by default, so the cup you put down five minutes ago beats the one from last week.

    Novelty: knowing when to speak

    The call I care most about for an assistant is predict_and_retrieve. It takes what you are looking at now, optionally runs it through a world model to predict what comes next, and searches memory for the closest match. Alongside the results it returns a novelty score between 0 and 1: one minus the best similarity, optionally calibrated against the history of scores. Near 0 means “I have seen this here before”. Near 1 means “this is new”. That single number is what lets the assistant stay quiet when nothing has changed and speak up when something has.

    Show me the code

    LOCI-DB is a Python library, Apache 2.0, and runs in-process with no server, Docker or GPU. This is the pendant’s memory in miniature, and it runs as written:

    # pip install loci-stdb
    import time, zlib
    import numpy as np
    from loci import LocalLociClient, WorldState
    
    memory = LocalLociClient(vector_size=128)
    
    def embed(label: str) -> list[float]:
        # Stand-in for a real image or label embedding (CLIP, DINOv2, ...)
        rng = np.random.default_rng(zlib.crc32(label.encode()))
        v = rng.normal(size=128)
        return (v / np.linalg.norm(v)).tolist()
    
    # Every detection from the pendant's camera becomes one memory:
    # WHAT it saw (a vector), WHERE (x, y, z in [0, 1]) and WHEN (ms).
    now = int(time.time() * 1000)
    sightings = [  # label, x, y, z, seconds ago
        ("cup",      0.48, 0.52, 0.40, 3 * 3600),
        ("keys",     0.12, 0.80, 0.55, 1800),
        ("scissors", 0.55, 0.50, 0.40, 600),
    ]
    for label, x, y, z, ago in sightings:
        memory.insert(WorldState(
            x=x, y=y, z=z,
            timestamp_ms=now - ago * 1000,
            vector=embed(label),
            scene_id=f"{label}@kitchen",
            confidence=0.9,
            metadata={"label": label, "room": "kitchen"},
        ))
    
    # "Where did I leave my cup?"  Similarity in, place and time out.
    hit = memory.query(vector=embed("cup"), limit=1)[0]
    mins = (now - hit.timestamp_ms) // 60_000
    where = f"({hit.x:.2f}, {hit.y:.2f}, {hit.z:.2f})"
    print(f"{hit.metadata['label']} at {where}, {mins} min ago")
    # cup at (0.48, 0.52, 0.40), 180 min ago
    
    # "What was on the table in the last hour?"
    # A box in space plus a window in time.
    table = {"x_min": 0.4, "x_max": 0.6,
             "y_min": 0.4, "y_max": 0.6,
             "z_min": 0.3, "z_max": 0.5}
    recent = memory.query(vector=embed("scissors"),
                          spatial_bounds=table,
                          time_window_ms=(now - 3_600_000, now),
                          limit=5)
    print([r.metadata["label"] for r in recent])
    # ['scissors']  (the cup is on the table too, but three hours ago)
    
    # "Is this new?"  0.0 = seen it here before, near 1.0 = new.
    for label in ["cup", "umbrella"]:
        r = memory.predict_and_retrieve(
            context_vector=embed(label),
            predictor_fn=lambda v: v,        # plug a world model in here
            current_position=(0.48, 0.52, 0.40),
        )
        print(label, round(r.prediction_novelty, 2))
    # cup 0.0
    # umbrella 0.96
    

    Swap LocalLociClient for LociClient("http://localhost:6333", ...) and the same code runs on a persistent Qdrant backend. In the real system the vector comes from the detector’s label rather than a stand-in, and positions come from where the object sits in the frame or, on the first Raspberry Pi prototype, from real 3D coordinates in metres.

    On the board, the firmware is ESP-IDF C. Stripped of logging, its main loop is short:

    // The pendant's main loop, simplified from firmware/esp32-p4-client/main/app_main.c
    for (;;) {
      if (button_down()) {             // push to talk
        record_and_ask();              // host answers; if it is unreachable,
        continue;                      // MultiNet7 on the board answers from the card
      }
      bool online = host_reachable();
    
      if (online && local_backlog_count() > 0)
        upload_one_backlog_frame();    // frames captured offline, original timestamps
    
      if (time_for_next_frame()) {
        if (online) live_frame();      // JPEG to the host, labels (and any audio) back
        else capture_to_card();        // no host: keep remembering to microSD
      }
      vTaskDelay(pdMS_TO_TICKS(5));
    }

    And because an assistant is increasingly an agent, LOCI-DB also ships an MCP server, so Claude or any MCP client can use the same memory:

    pip install "loci-stdb[mcp]"
    claude mcp add loci-memory --env LOCI_MCP_MODE=local -- loci-mcp
    # tools: remember, recall, novelty, trajectory, memory_stats

    Where it started: a Raspberry Pi and a depth camera

    The first LOCI Companion was not a pendant. It was a Raspberry Pi 5 in one hand, a Luxonis OAK-D Lite depth camera in the other, and a Bluetooth headset for asking questions. I walked around the house with it while LOCI-DB built up its memory.

    It worked, and better than I expected. The OAK-D Lite does a lot of the work on the camera itself: it runs an object detector (YOLOv6-nano) on its own chip and uses its pair of stereo cameras to measure how far away each object is, so every detection arrives with real 3D coordinates in metres, about ten times a second. Printed AprilTags on the doors told the Pi which room it was in and where it was standing, so positions were stored in room coordinates rather than relative to the camera. That made the answers properly useful. A typical one:

    “Your mug (I track it as a cup) was last seen in the kitchen, about 1 m into the kitchen and 1 m to your left as you walk in from the door tag, at table height. That was 40 seconds ago.”

    It could also answer “what changed in the kitchen?” (“the cup moved about 2 m”), it said honestly when it was asked about something it cannot recognise, like keys, and it remembered across restarts. Everything ran on the Pi: detection, memory, speech recognition and speech synthesis, with no cloud service involved.

    It also proved, very clearly, that nobody would wear it. Both hands were full, a USB cable ran between them, the camera could drop out when the power bank sagged, and there was a headset on top of all that. The memory was right. The body was wrong.

    What changed when I made it smaller

    The fix was to split the system in two. The pendant keeps only what has to be on your body: a camera, a microphone, a speaker, one button and a microSD card. The thinking moves to a host you own. That is why an ESP32-P4 board, a fraction of the size, weight and power draw of the Pi and depth camera, can run the same assistant: it does not have to do the heavy work, only see, listen, speak and never lose a memory.

    First prototypePendant
    On your bodyRaspberry Pi 5, OAK-D Lite, headsetOne ESP32-P4 board on a cord
    Object detectionOn the camera (YOLOv6-nano)On the host (YOLOv8n)
    Positions3D in metres, anchored to rooms by AprilTagsWhere the object sat in the camera’s view
    Asking a questionBluetooth headsetBuilt-in button, microphone and speaker
    Without a networkEverything local on the PiKeeps recording to microSD; answers common questions on the board
    WearableNo: two hands and a cableYes

    The trade is depth. The pendant has a single camera, so for now it says “on the right, in the middle area” instead of “1 m into the kitchen”. The memory layer did not change at all: the same LOCI-DB stores both, because a room coordinate and a position in view are both just a place and a time. Bringing room-level answers back to the pendant is one of the next steps, and the Pi rig stays on my shelf as the reference for what good looks like.

    Why a pendant

    The Pi rig settled what the device should not be. Glasses are the obvious choice and the wrong one for a first version: expensive, hard to fit, and a big ask for someone who does not already wear them. A phone has to be taken out and pointed, which means you only capture what you already knew was important. A pendant on a lanyard sits at chest height, sees roughly what your body is facing, leaves both hands free, and comes off in a second. It is also the cheapest thing to build and iterate on, which matters when you are one person with a soldering iron.

    What is on my desk today

    The current build is deliberately off the shelf, so anyone can reproduce it:

    PartWhat it does
    Waveshare ESP32-P4-WIFI6 Kit AThe brain. An ESP32-P4 handles the camera and on-device processing; a companion ESP32-C6 provides Wi-Fi 6 and Bluetooth. The kit includes the camera module and a speaker.
    NULLLAB PM11 battery module, 1200 mAhPower, so the device can be worn untethered.
    LanyardThe mount. Low-tech on purpose.
    LOCI-DBThe memory: what was seen, where and when, plus novelty detection.

    Where I am right now

    There is a working demo, end to end. The board streams frames to the host, I hold the button and ask “where is my cup?”, and the answer plays from the speaker about 1.3 seconds after I let go. On the home network a frame makes the round trip in 70 to 240 ms; through the Cloudflare Tunnel, 200 to 400 ms. With the host switched off, the board recognised “where is my cup” on its own in 730 ms and played the cached answer from the card. The video at the top of this post is that loop, unedited.

    The Raspberry Pi and OAK-D Lite rig did its job: it proved the memory works with real 3D positions and room-level answers. It is retired as the main prototype now, and stays as the benchmark the pendant has to catch up with on the “where”.

    What I do not have yet is a prototype I would hand to someone else. That is the next milestone.

    The hard problems

    Four problems decide whether this becomes something people actually wear:

    • Privacy. This is the first problem, not the last. A camera on your chest sees other people, and a memory of your day is the most personal dataset you will ever own. My default is that images stay on the device or on hardware you own, that what gets stored is memory rather than video, and that the assistant can be told to forget. This is the same principle behind Enclave, my other project on keeping sensitive data out of reach of the models that use it.
    • Power. Continuous vision on a 1200 mAh battery is a budget problem. The device has to choose when to look, not stare all day.
    • Latency. An answer that arrives three seconds late is an answer about where you used to be. Deciding what runs on the ESP32-P4 and what runs elsewhere is the central architecture question.
    • Trust. If it is confidently wrong once in a way that matters, people stop wearing it. It has to know when it does not know, and say so.

    What is next in the series

    1. Part 2: The hardware. The full parts list, wiring, the enclosure and what I would change.
    2. Part 3: Giving an assistant a memory. LOCI-DB in depth: storing observations from a moving wearer, the benchmarks, where it is slow, and how novelty decides when to speak.
    3. Part 4: Privacy and power. What runs on the device, what never leaves it, how forgetting works, and the battery numbers.
    4. Part 5: First wearers. Putting the prototype on people who are not me, and what they tell me.

    If you build wearables, work on personal AI or accessibility, or simply have a strong opinion about whether you would wear one of these, I would like to hear from you. Subscribe below to get each part when it is published.

  • Agents Don’t Need a Better Harness. They Need a Kernel.

    Most of what we call “agent infrastructure” today is a harness: a loop that wraps a model call, bolts on some tools, and hopes the important state survives until the next turn. That was fine when agents ran for minutes. It breaks when they run for weeks.

    I’ve been writing about this from the leadership side — that context is the real work, that agents need commander’s intent rather than step-by-step orders, that the compiler is giving way to natural language. This post is the systems side of the same argument. If agents are going to be long-lived colleagues rather than clever autocomplete, they need something the industry solved fifty years ago for programs: a kernel.

    The harness hits a ceiling

    A harness is built around a single conversation. Its unit of work is the turn; its memory is whatever fits in the context window plus whatever someone remembered to write to a vector store. Ask it to run for a month — watching a codebase, operating a fleet, managing a research program — and the same failures show up every time:

    • Amnesia. State lives in the prompt, so it decays, gets summarized into mush, or disappears on restart.
    • No scheduling. Everything is synchronous. There is no clean way for an agent to sleep, wake on an event, or juggle ten threads of work at different priorities.
    • Ambient authority. Tools are handed over wholesale. Once the agent has a credential, every step of every task has it too.
    • No isolation. One confused sub-task can pollute the context, and the judgment, of everything else running in the same loop.

    We keep patching these with bigger context windows and cleverer prompts. That’s like fixing a lack of virtual memory by buying more RAM.

    What operating systems already figured out

    Early computers had the same problem. Programs ran one at a time, owned the whole machine, and lost everything when they stopped. The fix wasn’t faster programs; it was a layer underneath them that every program could rely on. A kernel gives you a small set of guarantees: processes that persist and can be paused and resumed, memory that is managed rather than hoped for, permissions enforced below the application, and a scheduler that decides what runs when.

    Map that onto agents and the shape of the missing layer becomes obvious.

    The primitives of an agentic kernel

    Persistent processes. An agent is not a chat session; it’s a process with an identity, a goal, and a lifetime measured in weeks. It can checkpoint, suspend, migrate between machines and resume without losing the thread.

    Managed memory. The context window is the agent’s registers, not its memory. Beneath it sits working memory, episodic memory of what happened and when, and semantic memory of what it knows. The kernel decides what gets paged into context for the task at hand. This is where context engineering stops being a craft and becomes infrastructure.

    Capabilities, not credentials. Instead of handing an agent an API key, the kernel grants narrow, revocable capabilities per task: read this repo, open a pull request, spend up to this budget. Least privilege enforced below the model, where a clever prompt can’t talk its way around it.

    Scheduling and interrupts. Agents should sleep until something matters — a deploy finishes, a metric crosses a line, a human replies — and then wake with the right context loaded. Priorities, deadlines and budgets are scheduler problems, not prompt problems.

    Isolation and IPC. Sub-agents run in their own address space and talk through explicit messages. A failing child gets killed and restarted; it doesn’t contaminate its parent’s reasoning.

    An audit trail. Every action, every capability used, every decision point, recorded. If agents are going to act on our behalf, we need the equivalent of system logs before we need a better model.

    Where intent lives

    Here the leadership and systems arguments meet. In a harness, intent is a paragraph at the top of a prompt that slowly gets buried. In a kernel, intent is a first-class object: the goal, the constraints, what “done” looks like and what must never happen. It travels with the process, is visible to every sub-agent, and is what the kernel checks actions against. That is commander’s intent, expressed as an operating-system primitive.

    Why this matters beyond engineering

    For leaders, the kernel question is really a governance question. You cannot responsibly hand an organization’s work to agents that forget, can’t be paused, and hold every key at once. The teams that win the next few years won’t be the ones with the cleverest prompts. They’ll be the ones who build — or adopt — the substrate that makes agents persistent, bounded and accountable.

    I’m sketching a specification for exactly this kind of runtime, and testing pieces of it in my own projects: spatial and temporal memory in LOCI-DB, capability-scoped data access in SLM Vault. More on both soon. If you’re working on the same problem from a different angle, I’d like to compare notes.

All articles, essays, opinions and other materials on this site are my own and do not represent the views of my employer or any organization I am affiliated with.