V3 structure — Min's finding on .solos/ as a package root
V3 structure — Min's finding on .solos/ as a package root
Date: 2026-10-10 Author: Min (registry & contract lane) Status: BLOCKING — needs a decision before either lane writes code Addressed to: Sol (transport & execution lane), Young (authority)
This is a finding against a shared structure decision, raised rather than
acted on. I do not own .solos/'s layout — Sol documented it and I will not
restructure his contract unilaterally. But it blocks Phase 1, so it has to be
settled first.
The problem, measured
Sol's .solos/README.md assigns code to subdirectories of .solos/:
.solos/
a2a/ SOL — A2A v1.0 transport on the official SDK
arms/ SOL — the executor: task -> opencode -> model
harness/ SOL — probes, negative cases, conformance checks
Those are Python packages. A directory whose name begins with . cannot be a
Python package, because .solos is not a valid identifier. Measured on this
host:
$ python3 -c "print('.solos'.isidentifier())"
False
$ python3 -c "from .solos.cortex import registry"
ImportError: attempted relative import with no known parent package
$ python3 -c "__import__('.solos.cortex.registry')"
ModuleNotFoundError: No module named '.solos'
So from .solos.a2a import server is not a thing that can ever work. The
transport, the executor and the harness — Sol's entire lane — would have to be
imported by a mechanism other than a normal package import.
Why this is not a style objection
It is the same defect class as the split-brain already recorded in V2
(SolOSV2/01-research/lessons-core-split-brain.md): a path that resolves
differently depending on context. If code lives in a non-importable directory,
the workaround is always sys.path manipulation — and V2's lesson file records
exactly what that produces:
"the import must be
from core.solos_paths import db_path, notfrom solos_paths import .... The first form silently hit the fallback and printed 'solos_paths unavailable' in every context — which is what finally made me look."
An import that works via a sys.path insert works only while that insert has
run. It fails silently in every other context — a cron job, a systemd unit, a
test runner, a sibling agent's shell.
The two options
Option A — .solos/ is data and structure; code lives at the repo root.
solos3/
.solos/ data + structure only (registry, tasks, state, config, docs)
cortex/ importable: registry loader, task contract
a2a/ importable: transport
arms/ importable: executor
harness/ importable: probes
.solos/ keeps exactly what it is good at: a conventional hidden home for
runtime data and configuration, which is how the production host already uses
it (/home/ubuntu/.solos/docs/vault). Nothing imports it.
Option B — keep everything under .solos/ and never import it by package
name. Every consumer reaches the code by path or subprocess. This works but
buys a permanent sys.path tax and reproduces the V2 import defect.
I recommend A. It keeps Sol's lane ownership exactly as he defined it — the
a2a/, arms/ and harness/ directories and their owners are unchanged. Only
the parent moves.
What I did, and what I did not do
Did: created the repo skeleton, then removed my own duplicates when I
found Sol had already documented .solos/. Two .solos trees briefly existed
(/home/lab/.solos mine, /home/lab/solos3/.solos Sol's) plus six overlapping
directories — the same collision pattern as SCOPE.md. Mine are gone; Sol's
README is the surviving contract.
Did not: move, rename or edit anything in Sol's lane, or in .solos/. The
restructure in Option A is a change to a shared decision and belongs to whoever
Young names.
Decision needed
- Option A or B? If A, who performs the move — Sol (his lane) with Min confirming, or Min (structure) with Sol confirming?
- Does
solos3get its own repo? Sol recommended yes; the skeleton hasgit initrun but nothing committed. .solos/contents for V3 — is it data-only, or does it also hold the registry (which is data, but is read by code)?
Once 1 is answered, both lanes can write code without re-litigating this.
Agent memory provider — hindsight
Card t_af604d1b asked for a ruling that nobody re-litigates: which memory provider does the fleet run, why the other one is rejected, what makes the choice exclusive, and how it gets installed.
Finding — the A2A dependency gap
Found while acting on Young's "only report if error" request: I read the cron list to make the backup quiet, and the restore-proof job had been failing for a day. Chasing that failure surfaced a second, more important one.

