Разделяйте владение artifacts до параллельного запуска
Самый надёжный способ избежать конфликтов - не давать независимым workers писать в один объект. Каждый work item объявляет write set; control plane сравнивает фактические outputs с декларацией. Для файлов это paths или globs, для базы - entity keys, для документов - sections, для внешних систем - конкретные resource ids и операции.
readonly #items = new Map<string, Artifact>();
readonly #contracts: ReadonlyMap<AgentId, AgentContract>;
public constructor(contracts: readonly AgentContract[]) {
this.#contracts = new Map(contracts.map((contract) => [contract.id, contract]));
}
public write(writer: AgentId, draft: ArtifactDraft): Artifact {
const contract = this.#contracts.get(writer);
if (!contract) {
throw new Error(`Unknown agent ${writer}`);
}
const allowed = contract.allowedWritePrefixes.some((prefix) => draft.key.startsWith(prefix));
if (!allowed) {
throw new Error(`Agent ${writer} cannot write ${draft.key}`);
}
const current = this.#items.get(draft.key);
const currentVersion = current?.version ?? 0;
if (currentVersion !== draft.expectedVersion) {
throw new ArtifactConflictError(
`Version conflict for ${draft.key}: expected ${draft.expectedVersion}, actual ${currentVersion}`
);
}
const artifact: Artifact = {
...draft,
version: currentVersion + 1,
writer
};
this.#items.set(draft.key, artifact);
return artifact;
}
public read(key: string): Artifact | undefined {
return this.#items.get(key);
}
public list(): readonly Artifact[] {
return [...this.#items.values()].sort((left, right) => left.key.localeCompare(right.key));
}
}Стратегия записи зависит от того, насколько объект общий - и выбор стоит сделать до запуска.
Стратегия · Когда применять · Что проверять
- Single writer - Критический общий artifact; Все workers возвращают proposals, writer применяет их
- Disjoint partitions - Независимые файлы или records; Непересекающийся write set до запуска
- Optimistic concurrency - Редкие конфликты; expectedVersion и retry с новым read
- Deterministic reducer - Map/reduce outputs; Schema, dedupe key и стабильный merge order
- Human merge - Семантически конфликтующие решения; Явные alternatives и evidence
Git worktree решает не всё. Разные worktrees изолируют filesystem checkout, но два агента всё равно могут изменить один логический контракт разными способами. Merge conflict отсутствует, если строки разные, а архитектурный конфликт уже существует.
В companion-проекте tester пишет только в evidence/tests/, security worker - только в evidence/security/, docs worker - только в release-notes/. Reviewer читает эти artifacts и владеет report/. Ограничения исполняет store, а не просьба в prompt.
Владение разделено. Теперь параллельный запуск: планировать надо ready set, а не очередь разговоров.