Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
066b11a
Add Project repository associations and non-destructive Owner closure
zy95-12 Nov 2, 2026
61e0abc
Separate personal-agent identities from Project participations
zy95-12 Nov 2, 2026
6eeba41
Authenticate scoped personal-agent connections with existing delegati…
zy95-12 Nov 2, 2026
b4fa8de
Preserve Task-role definitions and latest SDK session across retries
zy95-12 Nov 2, 2026
439a41c
Expose durable handoff contracts and private consultation flows
zy95-12 Nov 2, 2026
a9ff63b
Bound role context and retain scoped memory and working summaries
zy95-12 Nov 2, 2026
6ebc706
Cover scoped memory source pages and record real SDK continuation val…
zy95-12 Nov 2, 2026
4101275
Deliver fresh native Chief job context in the resident Session turn
zy95-12 Nov 2, 2026
70fbe82
Admit Project Tasks through Chief and resume parents after child results
zy95-12 Nov 2, 2026
4826723
Adjudicate dependency exceptions and admit verified child integration…
zy95-12 Nov 2, 2026
8f7dffa
Persist runtime state and Effects atomically in optional SQLite storage
zy95-12 Nov 2, 2026
90dfcc8
Unify durable command recovery and committed Project event interfaces
zy95-12 Nov 3, 2026
dba40f8
Require approved durable Project role changes
zy95-12 Nov 3, 2026
3e90554
Integrate approved role governance with personal agent identities
zy95-12 Nov 3, 2026
3629495
Integrate approved roles with current personal agent authorization
zy95-12 Nov 3, 2026
cbab78a
Merge branch 'feat/2183-agent-auth' into feat/2184-execution-lifecycle
zy95-12 Nov 3, 2026
a11696d
Require native execution quiescence before releasing Task context
zy95-12 Nov 3, 2026
f404153
Execute custom Project roles with pinned capability policies
zy95-12 Nov 3, 2026
32f7941
Activate exact native context before resuming pool handoffs
zy95-12 Nov 3, 2026
3f7fe22
Require consistent native exit proof across pool and supervisor recovery
zy95-12 Nov 3, 2026
29f0e02
Revalidate retained role execution and stop revoked claims through ex…
zy95-12 Nov 3, 2026
36210b9
Compose current execution and role governance with durable handoff co…
zy95-12 Nov 3, 2026
c16a25e
Compose bounded role context with current native execution and govern…
zy95-12 Nov 3, 2026
54a6bb5
Compose canonical Task waits with retained roles and fence changed re…
zy95-12 Nov 3, 2026
9d3ab4e
Compose transactional state and verify native continuation from commi…
zy95-12 Nov 3, 2026
cca28b2
Retain active-memory reference after preserved historical inventory
zy95-12 Nov 3, 2026
cbab790
Compose current execution into service queries, governance commands a…
zy95-12 Nov 3, 2026
dfde85c
Merge branch 'feat/2182-transactional-state' into feat/2185-service-c…
zy95-12 Nov 3, 2026
6e677c8
Keep role metadata reads pure and preserve complete policy within its…
zy95-12 Nov 3, 2026
86e8b6e
Initialize the custom artifact catalog through explicit owner configu…
zy95-12 Nov 3, 2026
20771d6
Sync delivery integration ancestry for #2250
zy95-12 Nov 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions LESSONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,10 @@ Seen 1× while implementing #2179. Reusing old group aggregation would accept ca

An interrupted prepared SQL migration may recover its verified import; an active database that disappears must fail closed, not silently revive the old import. Publish a newer-version JSON guard before initialization, validate one authority, and retain a fenced resumable rollback marker across partial moves. A transaction commit must precede Effects acknowledgement without a fallible post-commit read masking that proof.

### 2026-11-03 — A failed acceptance save is not a valid retry result

Pool acceptance previously left an active claim in memory when saving failed; repeating its idempotency key could return that uncommitted claim. Persist an acceptance marker, roll back failed ownership and require commit proof on replay. Public command replay must similarly bind exact intent/result and current principal while allowing the original successful generation to advance. Keep unknown outcomes explicit; receiving a fact does not grant initiative.


### 2026-11-03 — Public Chief cannot borrow its approver's identity

Expand Down Expand Up @@ -755,3 +759,11 @@ Seen 1× (late Task requirement response regression). Stopping on the next sched
### 2026-11-03 — State maps do not encode chronology

Seen 1× (actual SQLite native return probe). Two valid Attempts survived, but UUID-key SQL iteration put the successor first and an insertion-order assertion compared it to itself. Use persisted predecessor references for chronology; preserve explicit history positions. Storage order must not decide current execution or evidence.

### 2026-11-03 — New execution adapters need committed read-model coverage

Seen 1× (native projection regressions). A correct native stop/binding is insufficient if queries/events still report only SDK workers. Reuse actual activation/exit proofs, distinguish current catalog from frozen definition, hide host details and reference large definitions instead of repeating them. Keep private personal proposals separate from public governance proposals.

### 2026-11-03 — Read-model lookups must not materialize domain facts

Seen 1× (actual SQLite API regression). A Task query requested full delivery definitions, creating an unsaved default role catalog. A later Task command persisted it and emitted an unrelated Project change. Return deterministic legacy defaults without mutation and use committed raw catalogs for metadata; keep materialization in explicit writes.
60 changes: 9 additions & 51 deletions PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,57 +150,9 @@ return/retry/re-review and scripted owner acceptance. Workers/workspaces were re
[Evidence](dev/demo/evidence/codex-2026-11-01.json) distinguishes this from the outstanding
Claude/mixed-resource/browser/restart criteria and independent repository review.

### Collaboration repairs — 2026-11-01

The owner authorized sequential issues [#34–#41](https://github.com/zy95-12/FlyBot/issues/33), one PR each; see [decision](decisions/2026-11-01-collaboration-repair.md). The target is native multi-Bot reuse, per-Bot pools and enforced handoff, restored role contracts, ordinary Chief conversations, safe/watch delegation and configurable Chief inspection schedules. Public hosting is deferred; control-plane stays unchanged.

R1 (#34) rejects incomplete repository capabilities before workers/workspaces/leases are allocated. Workbench readiness checks Git/runtime/dependency metadata and reports the precise block; this does not claim tests or SDK task delivery have run. Old failed Attempts remain readable. R1 full local verification passed in PR #42; actual shared-service integration remains pending.

R2 (#35) restores complete Dev/Tester/Reviewer conventions, pinned policy-source hashes and final-execution prompt assembly for native and SDK roles. FlyBot code sealing requires memory/tests/architecture evidence; candidate approval explicitly cannot mint a signed forge PASS. Focused tests cover full rules reaching SDK input, required-source failures and tampering. R2 full verification and later backend/dogfood acceptance are tracked separately.


R3 (#36) implements per-logical-Bot pools on existing Task records, atomic claims,
versioned receipts and enforced handoff admission. New shared deliveries default
to dynamic pool dispatch; the legacy DAG is explicit opt-in. Only the receiving
role allocates an execution Session/resource. Candidate returns retain the Task
and create a new Attempt; overall completion waits for Chief judgement. Unit and
SDK contract-process tests cover non-DAG return/rework with one resource. Full
verification, conversation bridging, Chief arbitration/schedules and real shared
service dogfood remain separately tracked acceptance, not implied by these tests.


R4 (#37) adds conversation-only private → Chief → original-chat handoff, isolated
from private memory and other members. Query turns cannot publish or execute a
Task; scoped GitHub reads provide actual repository facts. Impactful Task kinds
persist across proposal publication; workbench status separates publication from
queue/start/execution and Chief wait. Targeted privacy, native/SDK-query, no-Task
and credential/revocation tests pass. Full verification and real shared-service
acceptance remain separate; control-plane and public hosting are unchanged.


R5 (#38) implements safe/private publication proposals and persistent, revocable
watch grants bound to the current human and Project. Browser logout does not
revoke watch authority; account/membership/grant changes do. Scoped actions use
current human rights and retain provenance. The unchanged SQLite platform can
supply fresh account status through a FlyBot-owned read-only operator helper,
without storing browser cookies or admin credentials. Regression tests cover
logout, restart, current rights, revocation, forged status evidence and fresh WAL
reads. Shared-service provisioning and real-model acceptance are still pending.

R6 (#39) adds evidence-gated Chief arbitration, audited intervention and configurable
inspection on original DSH scheduled tasks. The JSON template defaults to 30 minutes;
content, cadence, thresholds and pause/enable are editable. Current configured human
authority and generation fences apply to each effect. Unknown process exits retain
capacity; a verified systemd invocation boundary permits local restart recovery.
Deterministic protocol tests return incomplete coverage to Dev then close the same
Task after a fresh Attempt. Real shared-service Codex/timer acceptance remains #41.

Real shared-service R6 probes passed an actual Codex Chief ordinary inquiry with
zero Tasks and an original DSH 60-second wake after browser logout, then pause/
resume and restoration to 30 minutes. R7 actual Dev requested Chief arbitration;
Chief returned the same Task to Dev with a fresh Attempt. This exposed a concurrent
resource-release reconciliation race, fixed with a red/green regression. Actual
full R7 delivery and persistent 30-minute/restart acceptance remain in progress.
### Collaboration contract and earlier validation

Native multi-Bot UI, per-Bot handoff pools and complete pinned role conventions remain required. Ordinary Chief questions are conversations; safe/watch delegation uses current human permissions. Chief inspection uses the original DSH scheduled-task service with editable cadence/content/thresholds (the current template defaults to30 minutes), never a hardcoded framework workflow. Code changes retain required memory/tests/architecture evidence. Earlier R1–R7 implementation and runtime validation are [preserved verbatim](docs/history/2026-11-03-collaboration-repair-evidence.md). Current acceptance follows the convergence records above; no new deployment, Control Plane change or interruption of healthy frontend work is authorized.

### Collaboration execution invariants and historical evidence

Expand Down Expand Up @@ -323,6 +275,12 @@ New shared Tasks have Chief admission and versioned requirements. Existing Task/

Opt-in SQL retains the original Store/services and saves domain facts plus Effects atomically. JSON becomes a newer-version migration guard, with verified import/recovery and offline export/rollback; no dual writable snapshots. Histories are normalized and large immutable payloads hash-referenced. Routine state updates/views make no additional model calls or Project-position changes. Full-state hydration/scanning remains; storage growth is distinct from #2177 context budgets. No live migration or provider-loop claim.

### 2026-11-03 — Service contracts (#2185)

The original application service adds private principal-scoped command receipts, bounded Task/Attempt sources, committed snapshots/events and authenticated resumable SSE. Unknown command outcomes are reconciled explicitly, never blindly rerun. Independent personal-agent identity survives carrier/transport rotation. Role acceptance commits before ownership can be replayed. Event receipt grants no role authority; private chat/auth/receipt writes do not affect public Project streams. Existing UI remains; #2186 compatibility and #2189 real deployment/README follow.

Composition checkpoint: current role governance/native exit, bounded context and canonical Task waits now share one execution chain. Native input fences logical role/physical worker separately; Task requirement revision changes stop the old Attempt through existing pool release. Actual composed/native acceptance and remaining API/storage compatibility are still under verification, not deployment.

SQLite composition now has an actual DSH native return probe: canonical Chief intake, persisted activation/exit, original role context and single-resource handoff are read from committed SQL snapshots. Inference remains deterministic; no production migration or full-provider workflow acceptance is claimed.

Service composition adds scoped native execution/exit and current-vs-pinned role metadata, role governance aliases, and bounded per-entity committed snapshots. New projections and final six-case DSH/SQLite validation are under current review; none of this branch is deployed.
2 changes: 2 additions & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ New shared Tasks have Chief admission and versioned requirements. Existing Task/

#2182 implements opt-in transactional SQLite through the existing Store, exact-identity migration, process-death commit tests and recoverable offline rollback. Retain configured Chief semantic decisions while routine facts/queries remain deterministic. Public scoped event/receipt service #2185, legacy entrypoint cutover #2186 and final real deployment/README #2189 remain subsequent stages; current production state is unchanged.

#2185 unifies command recovery, bounded history/source queries and committed Project event/SSE transport over existing services. Verify persistence failure/restart, current permissions and source hashes separately from model development. Complete legacy interface/cutover compatibility #2186 and original role/native-session dependencies before the final #2189 deployment/README rewrite.

Native prior-host reconciliation now reuses verified supervisor process-group facts; native v2 registered-work/lineage and shared adapter-exit regressions guard against premature initiative transfer. In-flight current-rights abort and composed-stack acceptance remain active.

Canonical ongoing role/resource authority checks now reuse native step/SDK input and the existing scheduler + pool stop. Frozen role context remains stable; current revoked rights stop execution, with unknown exit held. Compose descendants and verify parent Task resume/API projections next.
1 change: 1 addition & 0 deletions changelog.d/2185.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add durable principal-scoped command receipts, bounded Task/Attempt history sources and committed Project snapshots/events with authenticated resumable SSE; fence failed Handoff acceptance and preserve private-agent boundaries. Compose native activation/exit and role-governance facts into bounded queries/events, retain exact frozen-definition references, and expose existing governance through scoped v1 aliases with receipt replay. Keep implicit default catalogs read-only so ordinary queries cannot create unrelated Project changes on a later write.
12 changes: 7 additions & 5 deletions core/src/host/project-agents.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,19 +109,19 @@ export function createProjectAgents(rt) {
rt.requireProjectAccess(authority.actor, authority.agent.projectId)
return authority
}
function storedDefinitionSet(projectId) {
const existing = ownEntry(definitions(), projectId)
function storedDefinitionSet(projectId, materialize = true) {
const existing = ownEntry(state.projectAgentDefinitions ?? {}, projectId)
if (existing) return existing
const model = rt.config.projectModel ?? rt.cachedDefault?.() ?? ''
const workerNodes = deliveryGraph(model).nodes
const rows = [{ role: 'chief', name: 'Chief', instructions: CHIEF_PROMPT, model, skills: ['project-context', 'task-planning'], tools: [] },
...workerNodes.map(node => ({ role: node.id, name: node.name, instructions: node.prompt, model: node.model,
skills: node.id === 'developer' ? ['code-change'] : node.id === 'tester' ? ['test-evidence'] : ['commit-review'], tools: [] }))]
const record = { projectId, revision: 1, roles: rows.map(row => ({ ...row, id: `${projectId}:${row.role}`, memoryRefs: [], execution: { harness: 'flybot', resourceIds: [] }, toolPolicy: row.role === 'chief' ? { kind: 'scoped-project', filesystem: false, connectors: [] } : { kind: 'registered-worktree', shell: true, connectors: [], isolation: 'cwd-only' } })) }
setEntry(definitions(), projectId, record)
if (materialize) setEntry(definitions(), projectId, record)
return record
}
function definitionSet(projectId) { return roleGovernance ? roleGovernance.visibleSet(projectId, storedDefinitionSet(projectId)) : storedDefinitionSet(projectId) }
function definitionSet(projectId) { return roleGovernance ? roleGovernance.visibleSet(projectId, storedDefinitionSet(projectId, false)) : storedDefinitionSet(projectId, false) }
async function prepareDefinition(role, body, projectId) {
if (body.tools !== undefined && !Array.isArray(body.tools)) throw refuse('Invalid role tools')
if (Array.isArray(body.tools) && body.tools.length) throw refuse('Agent connector tools need explicitly delegated credentials')
Expand Down Expand Up @@ -150,7 +150,7 @@ export function createProjectAgents(rt) {
rt.projectResources?.checkPool(projectId, next.execution)
return next
}
roleGovernance = createProjectRoleGovernance(rt, { definitionSet: storedDefinitionSet, prepareDefinition,
roleGovernance = createProjectRoleGovernance(rt, { definitionSet: storedDefinitionSet, readDefinitionSet: projectId => storedDefinitionSet(projectId, false), prepareDefinition,
baseDefinition(projectId, role) {
const active = definitionSet(projectId).roles.find(row => row.role === role)
if (active) return structuredClone(active)
Expand Down Expand Up @@ -196,6 +196,8 @@ export function createProjectAgents(rt) {
return known
}
if (project.status !== 'active') throw refuse('Project is archived; a new agent cannot be created')
// Creating an actual carrier is a write; metadata reads only peek defaults.
storedDefinitionSet(projectId)
let bot
if (visibility === 'public' && !room) {
const previous = project.chief
Expand Down
Loading
Loading