diff --git a/BRAIN_ONLINE_INTEGRATION.md b/BRAIN_ONLINE_INTEGRATION.md index 5a23579..2b6e3ee 100644 --- a/BRAIN_ONLINE_INTEGRATION.md +++ b/BRAIN_ONLINE_INTEGRATION.md @@ -141,7 +141,7 @@ remains unverified. HTTP witness SHA-256: `1e545a0d0dca944e0daaae73d21486e4e00a92e0ba90b4bf5bd7be5644361bb4`. The private bearer file is -`C:\Users\Moe\Documents\ChatGPT\FACTORY\.factory\viewer\credential.json`. +`.factory\viewer\credential.json`. It contains `{ "token": "..." }` under owner-only Windows permissions. Load it only into the server-side brain-online adapter; never expose it to its browser, Git, logs or process arguments. FACTORY's `loadViewerToken` checks file ownership, @@ -152,7 +152,7 @@ commit. The currently running process was launched earlier from `8f5a940`: ```powershell $factoryBuild = (git rev-parse HEAD).Trim() -& 'C:/Users/Moe/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node.exe' bin/serve.mjs --database 'C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/federation-20261002/control.sqlite' --spending-ledger 'C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/spending.sqlite' --factory-id factory-live-pilot --token-file 'C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/viewer/credential.json' --modal-journals 'C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/viewer/modal-journals-20261003.private.json' --port 4344 --build-revision $factoryBuild +& 'node' bin/serve.mjs --database '.factory/federation-20261002/control.sqlite' --spending-ledger '.factory/spending.sqlite' --factory-id factory-live-pilot --token-file '.factory/viewer/credential.json' --modal-journals '.factory/viewer/modal-journals-20261003.private.json' --port 4344 --build-revision $factoryBuild ``` Shared paid reservations live separately in `.factory/spending.sqlite`: $10 Fly diff --git a/FACTORY_DESIGN.md b/FACTORY_DESIGN.md index 0f338ee..8f78f46 100644 --- a/FACTORY_DESIGN.md +++ b/FACTORY_DESIGN.md @@ -4,7 +4,7 @@ Version 0.2 · October 2, 2026 · Discussion draft The notebook below records the original design assessment. Subsequent implemented and live-tested results are tracked separately in -[the qualification record](C:/Users/Moe/Documents/ChatGPT/FACTORY/QUALIFICATION.md). +[the qualification record](QUALIFICATION.md). ## Confirmed direction @@ -16,7 +16,7 @@ constraints. Track accepted-delivery throughput as a complementary measure. The owner also wants a network of FLUJO instances that can provision further cloud instances, pursue different problems and competing approaches, communicate, and monitor each other. The proposed architecture is a federation with delegated -budget and explicit authority; see [the federation design](C:/Users/Moe/Documents/ChatGPT/FACTORY/FEDERATION.md). +budget and explicit authority; see [the federation design](FEDERATION.md). The factory should eventually govern its own routine work and improve its methods. The operating model below is a proposal, not an implemented system or @@ -30,8 +30,8 @@ interruptions, and shows what changed and why. | Responsibility | Owner-designated chat | Observed context on October 2 | | --- | --- | --- | -| User experience / avatar interface | [Plan Fujo’s avatar interface](codex://threads/01a0fe99-5cef-76b2-8a84-67e9ee3f6d71) | Active interface implementation; its avatar/world connects to FLUJO's existing backend capabilities | -| FLUJO development | [Clarify task request](codex://threads/01a0feb8-d78c-7b03-8e13-caae7b35e4fb) | Owner-designated development chat; retrieved history contains only a placeholder and clarification reply | +| User experience / avatar interface | Plan Fujo’s avatar interface | Active interface implementation; its avatar/world connects to FLUJO's existing backend capabilities | +| FLUJO development | Clarify task request | Owner-designated development chat; retrieved history contains only a placeholder and clarification reply | | Factory operating model and federation | This FACTORY chat | Architecture discussion and design artifacts | These are ownership/context references. No assignments or messages were sent to @@ -300,12 +300,12 @@ now uses budget-only policy at paused epoch 5/revision 92, preserving its missio budget and historical records; see [BUDGET_GROWTH.md](BUDGET_GROWTH.md). The local recovery pilot is executable in this repository. Its saved evidence at -[the October 2 recovery report](C:/Users/Moe/Documents/ChatGPT/FACTORY/evidence/local-recovery-20261002/report.json) +the October 2 recovery report records real Git mutation followed by process termination before receipt, positive destination reconciliation, rejected stale authority and one delivered candidate. Both candidate implementations are fixed fixtures. This qualifies a local control/recovery mechanism, not model-driven FLUJO development or network -failover. See [README.md](README.md) for reproducible commands and boundaries. +failover. See [the pilot notes](PILOT_NOTES.md) for reproducible commands and boundaries. ## Decisions still open @@ -320,16 +320,16 @@ failover. See [README.md](README.md) for reproducible commands and boundaries. ## Local evidence reviewed -- [FLUJO foundation contracts](C:/Users/Moe/Documents/GitHub/FLUJO/docs/architecture/enduring-agent-foundation-contracts.md) -- [Behavior learning](C:/Users/Moe/Documents/GitHub/FLUJO/src/backend/services/enduringAgents/behaviorLearning.ts) -- [Behavior outcomes](C:/Users/Moe/Documents/GitHub/FLUJO/src/backend/services/enduringAgents/behaviorOutcome.ts) -- [Outcome policy](C:/Users/Moe/Documents/GitHub/FLUJO/src/backend/services/enduringAgents/behaviorOutcomePolicy.ts) -- [Persona review and delivery handoff](C:/Users/Moe/Documents/GitHub/FLUJO/docs/audits/2026-09-21-persona-review-handoff.md) -- [Runtime acceptance scope](C:/Users/Moe/Documents/GitHub/FLUJO/docs/performance/persona-runtime-soak-acceptance.md) -- [Hackathon product boundary](C:/Users/Moe/Documents/GitHub/factored-hackathon-2026/docs/FLUJO_PRODUCT_BOUNDARY.md) -- [Hackathon supervision](C:/Users/Moe/Documents/GitHub/factored-hackathon-2026/docs/HACKATHON_SUPERVISION.md) -- [Local CI policy](C:/Users/Moe/Documents/GitHub/factored-hackathon-2026/docs/LOCAL_CI.md) -- [Recorded October 2 pause and release handoff](C:/Users/Moe/.codex/visualizations/2026/10/01/01a0f97d-c4fa-7d51-bf5c-50edd8e7b1f4/manual-release/SESSION_HANDOFF_PAUSED.md) +- [FLUJO foundation contracts](https://github.com/mario-andreschak/FLUJO/blob/main/docs/architecture/enduring-agent-foundation-contracts.md) +- [Behavior learning](https://github.com/mario-andreschak/FLUJO/blob/main/src/backend/services/enduringAgents/behaviorLearning.ts) +- [Behavior outcomes](https://github.com/mario-andreschak/FLUJO/blob/main/src/backend/services/enduringAgents/behaviorOutcome.ts) +- [Outcome policy](https://github.com/mario-andreschak/FLUJO/blob/main/src/backend/services/enduringAgents/behaviorOutcomePolicy.ts) +- Persona review and delivery handoff +- [Runtime acceptance scope](https://github.com/mario-andreschak/FLUJO/blob/main/docs/performance/persona-runtime-soak-acceptance.md) +- Hackathon product boundary +- Hackathon supervision +- Local CI policy +- Recorded October 2 pause and release handoff - Selected coordination chats: `2h - FLUJO team coordinator`, `Inspect deployment and progress`, `1h - PR review automation`, and `24h - Fly deployment`. - [Official Codex App Server documentation](https://learn.chatgpt.com/docs/app-server). diff --git a/FEDERATION.md b/FEDERATION.md index 10c383a..e958970 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -12,7 +12,7 @@ throughput measure. Compare task classes and include review, integration and rew The owner's larger vision is a network of FLUJO instances that can deploy further cloud instances, work on separate problems or competing approaches, communicate, and monitor one another. This document extends the -[factory notebook](C:/Users/Moe/Documents/ChatGPT/FACTORY/FACTORY_DESIGN.md). +[factory notebook](FACTORY_DESIGN.md). ## A cell is a complete local work system @@ -223,7 +223,7 @@ separate clean `flujo-cloud` checkout at `c36ceef`. The cached newer FLUJO remot ref is context, not a claim about the currently deployed fleet. The local source audit found a portable workspace-snapshot cloud-worker path in -[Hot-clone workspace](C:/Users/Moe/Documents/GitHub/FLUJO/docs/features/hot-clone-workspace.md). +[Hot-clone workspace](https://github.com/mario-andreschak/FLUJO/blob/main/docs/features/hot-clone-workspace.md). Its documentation delegates Fly lifecycle, tunneling, forwarding and teardown to a separate `flujo-cloud` bridge and validates worker compatibility. @@ -232,8 +232,8 @@ The bridge already exposes a shared `ManagedCloud` application service with operation records a durable attempt before provisioning, pins a compatible image, and binds credentials to the deployment journal. `call` forwards an existing Flow request. These are concrete foundations for a factory provisioning capability. -See [the cloud architecture](C:/Users/Moe/Documents/GitHub/flujo-cloud/docs/architecture.md) -and [ManagedCloud](C:/Users/Moe/Documents/GitHub/flujo-cloud/lib/managed.mjs:253). +See [the cloud architecture](https://github.com/flujo-app/flujo-cloud/blob/main/docs/architecture.md) +and [ManagedCloud](https://github.com/flujo-app/flujo-cloud/blob/main/lib/managed.mjs#L253). The bridge exposes CLI/application-service operations. The factory adds a private MCP capacity tool, authenticated peer inbox and controller-admitted adapter. @@ -281,8 +281,8 @@ cross-host consensus. Remote MCP task polling can resume observation against a matching server identity, but its documented restart path does not retrieve and deliver results after the originating run is gone. These existing mechanisms cannot substitute for a durable cross-cell work/result protocol. See -[the local lease boundary](C:/Users/Moe/Documents/GitHub/FLUJO/docs/architecture/enduring-agent-foundation-contracts.md:52) -and [remote task recovery](C:/Users/Moe/Documents/GitHub/FLUJO/src/backend/services/mcp/remoteTaskResume.ts:3). +[the local lease boundary](https://github.com/mario-andreschak/FLUJO/blob/main/docs/architecture/enduring-agent-foundation-contracts.md#L52) +and [remote task recovery](https://github.com/mario-andreschak/FLUJO/blob/main/src/backend/services/mcp/remoteTaskResume.ts#L3). Established background patterns include lease-based coordination and durable workflow history/recovery. Kubernetes documents leases for heartbeats and leader @@ -297,7 +297,7 @@ The first partial live delegation proof has now passed: real parent/child FLUJO workers, coordinator-mediated child admission, independent review, owned teardown and a separate same-host provider witness. It does not yet qualify the full experiment below. Exact evidence and remaining scope are in -[the qualification record](C:/Users/Moe/Documents/ChatGPT/FACTORY/QUALIFICATION.md). +[the qualification record](QUALIFICATION.md). 1. Select one bounded FLUJO improvement and a common acceptance contract. 2. Provision one cloud development cell and an independently hosted watcher, diff --git a/FLUJO_OWNER_BRIDGE.md b/FLUJO_OWNER_BRIDGE.md index 5a36a78..a86a436 100644 --- a/FLUJO_OWNER_BRIDGE.md +++ b/FLUJO_OWNER_BRIDGE.md @@ -12,7 +12,7 @@ Twenty-four Node regressions passed for entry ordering, interruption, duplicate/ The isolated real-SDK exercise passed one case through FLUJO's actual OpenAiAdapter, installed OpenAI SDK 7.3.0, guarded final fetch and execution-extension dispatch. It produced one owner dispatch, unknown parent/child and zero attempts at all ten guarded transports. Expected body and headers come from independent fixture constants and pinned source, not from the observed request. No real credential was configured. Duplicate child use and restarted parent observation did not dispatch again. The SDK default client timeout does not add a request timeout header; the first incorrect header commitment remains a retained failed run with zero claims. -The corrected owner passed one new real-SDK entry at C:/Users/Moe/.codex/worktrees/factory-owner-lifetime-r2/FACTORY/.factory/flujo-owner-wire-sdk-run-438df4a3-a566-4484-af2f-a8f0e4a94af3. The [Root capture](C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/budget-growth-activation-20261003/root-owner-lifetime-sdk-actual-db8d3211-97a7-48ef-b3db-df228ef13251/records/run.private.json) records a closed successful launcher, 51 selected source/runtime files unchanged before and after, and 1/1 passing SDK case. Root re-read all 58 receipt/source/case inputs. The request body and headers remain exactly the independently committed bytes; one dispatch leaves parent and child unknown with all ten guarded transport counters zero. Duplicate/restart observation grants no second dispatch. A [renewed body link](C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/budget-growth-activation-20261003/root-owner-lifetime-pr35-body-link-377df079-e4db-4222-a940-6d535626a9ca/link.private.json) binds this new SDK receipt to the retained R4 normalized body result across 78 selected inputs. No receiver or provider was rerun for that link. The older SDK38af qualification and its earlier body link remain historical and unchanged. +The corrected owner passed one new real-SDK entry at .factory/flujo-owner-wire-sdk-run-438df4a3-a566-4484-af2f-a8f0e4a94af3. The Root capture records a closed successful launcher, 51 selected source/runtime files unchanged before and after, and 1/1 passing SDK case. Root re-read all 58 receipt/source/case inputs. The request body and headers remain exactly the independently committed bytes; one dispatch leaves parent and child unknown with all ten guarded transport counters zero. Duplicate/restart observation grants no second dispatch. A renewed body link binds this new SDK receipt to the retained R4 normalized body result across 78 selected inputs. No receiver or provider was rerun for that link. The older SDK38af qualification and its earlier body link remain historical and unchanged. The harness uses a sanitized environment and dedicated Next SWC/Jest configuration without application setup or .env loading. Its source-specific Windows/Node 24.19.0 pins are an offline qualification harness, not a portable worker package or complete dependency-closure proof. Its fixture/config live in scripts/fixtures, outside Node's default test discovery. Invoke the pinned Node executable with `scripts/flujo-owner-wire-fixture.mjs`. The prior owner profile passed at `.factory/flujo-owner-wire-sdk-run-38afccfd-ea42-4ccc-873e-340cc7ae73ab`; Root consumed 58 inputs and independent review consumed 59, including the post-close SQLite bytes. The earlier accepted receipt `71f070f3-7c7f-477e-892e-08c9b7457eb0` remains historical evidence, with the three earlier harness sources archived byte-for-byte. @@ -26,9 +26,9 @@ Run `scripts/communityai-receiver-fixture-r3.py` with the pinned bundled Python A separate R4 probe uses the selected CommunityAI PR35 server snapshot reported at f74e444aca25b3f6fa75107cbfd1b190cdb21395 (server.py SHA-256 9725a900ecfd565b1eb69ecc11888cf0a6494a985dccf28de353e3a0d7a34d60). Its extracted strict schema accepts the unchanged SDK-final body with stream_options.include_usage=true, retains that option, adds default n=1 and spells temperature as 1.0. The normalized SHA-256 is 21a0d9be9d903deba02504bb66506208338bc4423c8669a71db1904d21aa4890. An unknown nested stream option is refused. -Root captured one new isolated R4 entry with PID 18180 closed at exit 0, complete stdout and empty stderr. The script and twelve selected source/runtime files had exact Node ten-field path/descriptor identities before and after; the Python report matched those byte bindings. The [owned run record](C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/communityai-receiver-run-016aa0cf-620e-4848-a363-053dcdb5ed4e/records/run.private.json) retains raw-stream pins and the report. The [body link](C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/budget-growth-activation-20261003/root-owner-wire-pr35-body-link-a5b271cd-3e0a-4940-99ab-361e5e5d2fd0/link.private.json) explicitly binds accepted SDK38af body 44c04671db48d10c164afcdf6558032c4ca68cb8f0a1c5e9ebdaeb7f449843b5 to this R4 normalized result. Root rechecked 75 unique inputs; independent review rechecked those inputs and the link. This is a new cross-receipt schema/digest qualification. The old SDK receiver field and all earlier receipts remain unchanged. +Root captured one new isolated R4 entry with PID 18180 closed at exit 0, complete stdout and empty stderr. The script and twelve selected source/runtime files had exact Node ten-field path/descriptor identities before and after; the Python report matched those byte bindings. The owned run record retains raw-stream pins and the report. The body link explicitly binds accepted SDK38af body 44c04671db48d10c164afcdf6558032c4ca68cb8f0a1c5e9ebdaeb7f449843b5 to this R4 normalized result. Root rechecked 75 unique inputs; independent review rechecked those inputs and the link. This is a new cross-receipt schema/digest qualification. The old SDK receiver field and all earlier receipts remain unchanged. -Invoke the pinned bundled Python with -I -S -B and scripts/communityai-receiver-fixture-r4.py only in the documented offline harness. The exact adopted working-file bytes are 19,751 bytes, SHA-256 b75960f0ea688871c3e06b83e23642466259e4db1115c8b9598fd25666ca60eb. The earlier collaborator self-report remains at C:/Users/Moe/.codex/worktrees/factory-pr35-receiver-probe/FACTORY/.factory/communityai-receiver-pr35-run-921707de-8e65-4fee-a1f2-5a3d94e647ec/receiver.json; it did not retain an OS close/raw-stream wrapper. The R3 old-ingress refusal remains specific to its older snapshot. +Invoke the pinned bundled Python with -I -S -B and scripts/communityai-receiver-fixture-r4.py only in the documented offline harness. The exact adopted working-file bytes are 19,751 bytes, SHA-256 b75960f0ea688871c3e06b83e23642466259e4db1115c8b9598fd25666ca60eb. The earlier collaborator self-report remains at .factory/communityai-receiver-pr35-run-921707de-8e65-4fee-a1f2-5a3d94e647ec/receiver.json; it did not retain an OS close/raw-stream wrapper. The R3 old-ingress refusal remains specific to its older snapshot. R4 executes only four request-schema classes and two digest definitions extracted from pinned source. It does not run ASGI, original admission, authentication, route/model selection, response streaming, peer dispatch or a provider. The new normalized digest would require a new independently authorized original admission commitment; this fixture does not issue one or upgrade receiver qualification. @@ -86,11 +86,11 @@ The fixed Start → one Process graph with Process ID model-node and the single The fixture calls the exported runFlow inside the separate owner startFixtureFlow seam, after its immutable SQLite start witness. The engine, converter, Start/Process nodes, prompt renderer, ModelHandler, adapter routing, execution extensions and installed OpenAI SDK remain real. Named model/settings/storage/MCP/snapshot/statistics services use local fixed responses, with transport guards installed before app imports. The host binds the single graph, model node, ordinal zero and start witness through a private WeakMap. This untyped singleton host association does not authenticate a production issuer or reuse an Original parent claim. -The [Root R2 capture](C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/budget-growth-activation-20261003/root-real-flow-r2-actual-d981d5e7-1ed2-40d3-b1ed-d80c6dce3a87/records/run.private.json) records launcher PID 38508 and Jest PID 20640 both closed at exit 0, with 1/1 passing case. One real Flow entry produced exactly one issue and one owner dispatch. The independently fixed SDK body is 299 bytes, SHA-256 `b86e125b6a031a226acc03147b5d865402ad149a621626fcdbf7629f5541fd03`, including the system message, usage options and prompt_cache_key `flujo-c1c5k0kx`. The ten ordered non-auth headers retain SHA-256 `5c668061cec85492e188b639ee64c642ebbe255a2de197b738d4d05d69188389`. +The Root R2 capture records launcher PID 38508 and Jest PID 20640 both closed at exit 0, with 1/1 passing case. One real Flow entry produced exactly one issue and one owner dispatch. The independently fixed SDK body is 299 bytes, SHA-256 `b86e125b6a031a226acc03147b5d865402ad149a621626fcdbf7629f5541fd03`, including the system message, usage options and prompt_cache_key `flujo-c1c5k0kx`. The ten ordered non-auth headers retain SHA-256 `5c668061cec85492e188b639ee64c642ebbe255a2de197b738d4d05d69188389`. runFlow returned the expected error; the host rethrew its captured trusted PHYSICAL_SEND_HOLD sentinel, preserving the fixture parent and child as unknown. All ten guarded transport counters and forbidden service counters were zero through the native host process exit. Guards remained installed until that exit. Direct child closure is recorded; global descendant quiescence and native bypass closure are unverified. The fixed source profile covers 12,427 selected application/dependency files and is a source-specific overapproximation, not a portable package or complete process-closure proof. Root checked 12,438 selected inputs before and after; the inner launcher checked 12,437, all unchanged. -The [R1 failed capture](C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/budget-growth-activation-20261003/root-real-flow-actual-d5937198-c8dc-4e45-bdf1-9d2272a2407d/records/run.private.json) remains immutable. It reached the same one dispatch but its test rejected two legitimate local service calls. R2 admits only the exact public fixed-graph revision fingerprint and the fixed conversation's empty resource list, with required call-count assertions; it retains the empty credential assertion and denies other values. The model-bound credential stays empty. R2's source and receipt remain in the attached `factory-real-flow-probe` worktree, separately frozen from R1. No Original SQL, credential read, receiver route or provider request ran. +The R1 failed capture remains immutable. It reached the same one dispatch but its test rejected two legitimate local service calls. R2 admits only the exact public fixed-graph revision fingerprint and the fixed conversation's empty resource list, with required call-count assertions; it retains the empty credential assertion and denies other values. The model-bound credential stays empty. R2's source and receipt remain in the attached `factory-real-flow-probe` worktree, separately frozen from R1. No Original SQL, credential read, receiver route or provider request ran. The real ModelHandler derives a prompt-cache key and builds system-message content. OpenAiAdapter conditionally emits prompt_cache_key for supported providers. Those bytes differ from the earlier adapter-only SDK44 fixture. The selected PR35 request schema forbids that undeclared cache field; the existing Original envelope2 grammar also excludes stream_options and prompt_cache_key. Do not reuse the earlier 44→21 evidence as full Flow or Original child-body qualification. The owner-bound singlePhysicalAttempt catch refuses before the adapter's ordinary cache-removal retry. diff --git a/MODAL_OBSERVATION.md b/MODAL_OBSERVATION.md index 29401e8..d844460 100644 --- a/MODAL_OBSERVATION.md +++ b/MODAL_OBSERVATION.md @@ -14,7 +14,7 @@ The owner-private JSON file contains only this configuration: "journals": [ { "runId": "modal-20261002-r3", - "journalPath": "C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/modal-20261002-r3/modal.sqlite" + "journalPath": "/absolute/private/.factory/modal-20261002-r3/modal.sqlite" } ] } diff --git a/MODEL_STEP_JOURNAL.md b/MODEL_STEP_JOURNAL.md index c9abf32..3585259 100644 --- a/MODEL_STEP_JOURNAL.md +++ b/MODEL_STEP_JOURNAL.md @@ -82,7 +82,7 @@ Duplicate, restarted and interrupted parents remain observation-only. A committe Schema4 checks fourteen table names, twenty trigger names and twenty-six extension definitions. This does not validate all base DDL, views or indexes, confine an arbitrary writable database holder, or qualify old writer quiescence. Reopened ordinary controllers receive default-deny start functions. The private one-use gate is available only to the configured journal. -The [Root compatibility capture](C:/Users/Moe/Documents/ChatGPT/FACTORY/.factory/budget-growth-activation-20261003/root-parent-v4-actual-qualification-1838a1b8-68c1-42b7-a408-ea83efa81765/records/run.private.json) passed 147/147 cases, covering the 28 new parent-start cases plus existing schema3 journal, original contract and native worker cases. Twenty-six selected source/runtime files remained byte/generation stable; 264 owned post-close fixture files and the two actual journal racer outcomes were retained. Five test workers recorded zero transport attempts. The separately pinned SQLite racers do not inherit that transport preload. Independent review rechecked all 299 selected files. Earlier failed Root launches remain separate evidence: one refused the Windows preload path before fixtures, and one hit a too-short sixty-second limit with incomplete totals. Neither is promoted into the passing capture. +The Root compatibility capture passed 147/147 cases, covering the 28 new parent-start cases plus existing schema3 journal, original contract and native worker cases. Twenty-six selected source/runtime files remained byte/generation stable; 264 owned post-close fixture files and the two actual journal racer outcomes were retained. Five test workers recorded zero transport attempts. The separately pinned SQLite racers do not inherit that transport preload. Independent review rechecked all 299 selected files. Earlier failed Root launches remain separate evidence: one refused the Windows preload path before fixtures, and one hit a too-short sixty-second limit with incomplete totals. Neither is promoted into the passing capture. This API remains a synthetic logical journal. It does not enter FLUJO runFlow, issue a production credential, create a provider reservation, admit native POST or authorize physical sending. Envelope/body/receiver-profile qualification is unchanged. diff --git a/ORIGINAL_RECEIVER_V3_CANDIDATE.md b/ORIGINAL_RECEIVER_V3_CANDIDATE.md index c0391ce..ce8e262 100644 --- a/ORIGINAL_RECEIVER_V3_CANDIDATE.md +++ b/ORIGINAL_RECEIVER_V3_CANDIDATE.md @@ -4,7 +4,7 @@ The selected plan slot commits the call and model; recipient identity, build and generation; physical sender principal; credential owner, ID and immutable generation hash; exact POST URL, method, ten ordered non-authentication headers and their hash; exact raw UTF-8 SDK body, byte length and hash; and receiver profile plus normalized UTF-8 body, byte length and hash. Receiver profile version3 binds recipient identity/generation, ingress schema, normalizer and runtime hashes, endpoint, body policy, and the exact proxy-policy SHA-256 selected by the Original issuer. The full plan hash is in the signed Original specification, and that specification's hash is in the envelope. Changing the proxy policy requires a fresh selected binding, plan, task specification and Original signature. The comparison2 and held witness2 carry the wire, receiver, credential and sender commitments through distinct versioned hashes. -The checked-in [wire fixture](test/fixtures/real-flow-sdk-wire-299.json) copies the actual SDK-final `POST /v1/chat/completions` projection from the retained R2 real-Flow capture at `C:/Users/Moe/.codex/worktrees/factory-real-flow-probe/FACTORY/.factory/flujo-real-flow-run-77240bd7-83ec-407e-819f-a4db089c945f/cases/case-report.json`. Its body is exactly 299 UTF-8 bytes, SHA-256 `b86e125b6a031a226acc03147b5d865402ad149a621626fcdbf7629f5541fd03`, with a system message, `stream_options.include_usage`, and `prompt_cache_key`. The ten ordered non-authentication headers hash to `5c668061cec85492e188b639ee64c642ebbe255a2de197b738d4d05d69188389`. The fixture URL is deliberately non-routable. +The checked-in [wire fixture](test/fixtures/real-flow-sdk-wire-299.json) copies the actual SDK-final `POST /v1/chat/completions` projection from the retained R2 real-Flow capture at `.factory/flujo-real-flow-run-77240bd7-83ec-407e-819f-a4db089c945f/cases/case-report.json`. Its body is exactly 299 UTF-8 bytes, SHA-256 `b86e125b6a031a226acc03147b5d865402ad149a621626fcdbf7629f5541fd03`, with a system message, `stream_options.include_usage`, and `prompt_cache_key`. The ten ordered non-authentication headers hash to `5c668061cec85492e188b639ee64c642ebbe255a2de197b738d4d05d69188389`. The fixture URL is deliberately non-routable. `createOriginalReceiverV3HeldContract` takes host-installed `verifyOriginal` and `observeHeldProjection` callbacks. Its public `compareHeld` method takes only an unforgeable authenticated capability; the observer receives a selector without the expected body or profile. The observation must match the signed envelope's full wire, authenticated sender principal, credential identity/generation, receiver profile and normalized body, and must report `HELD_BEFORE_POST`. The test fixture now commits the independent 307-byte PR35 Python-normalized body (SHA-256 `ab288a143d34de92156f01d0d4c4f5d05bbdc51eda4a335e16c8816205cd08b7`), preserving Python's `temperature:1.0` instead of reserializing it in JavaScript as `1`. The tests provide a synthetic verifier and synthetic held observation. A caller-supplied observation never enters the API. Configuring a callback that merely echoes user input would defeat the trust model and is outside this candidate. diff --git a/PEER_MESSAGING.md b/PEER_MESSAGING.md index 144a7ba..e8fdd73 100644 --- a/PEER_MESSAGING.md +++ b/PEER_MESSAGING.md @@ -44,11 +44,10 @@ hosted high availability. ## Explicit CLI -Use Node 24 or newer. This machine's default Node is older; the bundled executable -is `C:/Users/Moe/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/bin/node.exe`. +Use Node 24 or newer. All operations require `--private-module ABSOLUTE_PATH`, selecting the trusted private-files helper. The existing helper is -`C:/Users/Moe/Documents/GitHub/flujo-cloud/lib/private-files.mjs`. It checks owner-only +`flujo-cloud/lib/private-files.mjs`. It checks owner-only Windows ACLs and file identity. Configuration must be owner-private. Select a new dedicated private data directory and an explicit peer database; existing shared directories are not reprotected. Keep config files, databases and TLS private key diff --git a/PILOT_NOTES.md b/PILOT_NOTES.md new file mode 100644 index 0000000..a4e1541 --- /dev/null +++ b/PILOT_NOTES.md @@ -0,0 +1,712 @@ +# FACTORY pilot notes + +> The engineering record from FACTORY's early pilot, kept as it was written. To use FACTORY today, start with the [README](README.md). + +For the installable local SDK, CLI, and MCP server, see [Public Factory interfaces](PUBLIC_SDK.md). +For current cross-product adoption and release gates, see [Integration status](INTEGRATION_STATUS.md). +Factory is available under the [MIT License](LICENSE). + +The factory's first mission is to improve FLUJO, optimizing the time from an +accepted requirement to independently accepted delivery within quality and cost +constraints. This directory contains the first runnable **local coordination and +recovery pilot**. The larger design is in [FACTORY_DESIGN.md](FACTORY_DESIGN.md) and +[FEDERATION.md](FEDERATION.md). + +## October 4 priority + +Make the supervised WebUI → Fly FLUJO workers → private Modal route usable first. +Development that produces and checks code comes next; broad scorecards, +polishing and audit expansion wait. + +The existing cloud lane is owned by Review linked Codex thread. +Its recorded acceptance +establishes one supervised text job through two Fly workers using private +Ollama Qwen3 4B on Modal, followed by exact completed-job recovery after restart +with no inference replay. The developer gave an incorrect arithmetic answer +and the reviewer corrected it. FACTORY read the public receipt and recovery +contract; that recorded scope does not include code tools or income. + +Reuse that working gateway and worker lane. Root/Auth own its code executor. +FACTORY provides the supplied-task and immutable test/result receipt +contract in [src/development-job-contract.mjs](src/development-job-contract.mjs). +Its 14 focused tests pass. bindDevelopmentJob() freezes the task, candidate +file hashes, executor build and fixed Node test target; projectDevelopmentJob() +checks an independently pinned supplied receipt against that binding. A passing +receipt marks the proposal checked with explicitly unauthenticated provenance. +Applied code remains not_applied, income remains no_evidence and admission is +NO_ADMISSION; external sends require the named owner bridge. + +The working Python cloud executor has its own supplied-result contract in +[src/python-cloud-job-contract.mjs](src/python-cloud-job-contract.mjs). +bindPythonCloudJob() freezes the selected task and Python source hashes; +projectPythonCloudJob() checks the retained original request and response bytes +against the operation and fixed injected arithmetic or invoice suite. Its 17 +focused tests pass. The original runner response must retain trustedSuite, +trustedMinimum and trustedSuiteComplete; the current MCP text projection drops +those fields and cannot substitute for the raw receipt. Passing evidence yields +checked with unauthenticated runtime/suite provenance, NO_ADMISSION, +not_applied and no_evidence. The existing Node contract remains separate. + +The adapter also accepted a retained original cloud request and response for a +CSV job: ten project cases plus three fixed arithmetic cases, minimum three, +with cleanup confirmed. This was a local projection of saved bytes with no job +replay. Task and executor labels were supplied retrospectively; the actual +executor build remains unknown. Its checked result retains NO_ADMISSION and +not_applied. The earlier invoice fallback's original wire bytes were not retained +and were not reconstructed for this check. + +The cloud owner's code acceptance record +reports a real three-test arithmetic run and a deterministic invoice fallback +that passed 13 CPU checks with cleanup confirmed. The generated invoice V5 +passed nine fixed cases but retains known whitespace/precision gaps. The phone +reviewer assessed text; independent code execution is a separate sandbox result. +FACTORY consumed that public record without replaying the job or inference. + +[modal/communityai_bootstrap.py](modal/communityai_bootstrap.py) now wires the +pinned Qwen3 1.7B manifest, two complementary block workers, a text peer and +the actual CommunityAI coordinator APIs. A supplied four-role formation retains +actual public TCP ports and application TLS; host admission and receiver +authentication must be supplied by its owner. The launch contract requires the +exact retained model index, derives both block selections and carries all five +worker consistency claims. Model files use a read-only declared snapshot; +locks and cache state use distinct writable directories for each role. +Forty-one focused checks passed in the combined main checkout, covering +planning, held lifecycle behavior and image export/build receipts. + +[modal/communityai_runtime.py](modal/communityai_runtime.py) adds the real TLS +DHT bootstrap entry point, actual public/listen port handling, one bounded +startup observation deadline, expiry/stop handling and cleanup without retry. +Lifecycle observer calls have a one-second return bound. A stalled startup +observer causes same-DHT shutdown and suppresses a concurrent final callback; +a stalled final observer is an error after shutdown. The retained record labels +both publication states, possible late daemon-thread side effects and unverified +descendant retirement. On Linux the CLI writes each small JSON record directly +to nonblocking stdout, so a full log pipe fails the publication instead of +holding the cleanup path. Callback return means only that publication code +returned; it does not prove external delivery. + +The [bootstrap watchdog](modal/communityai_runtime_watchdog.py) runs that CLI in +an isolated Linux process group, anchors the supplied expiry to a monotonic +deadline, requests stop and sends a hard kill if the child misses a seven-second +cleanup grace. It inherits the child's lifecycle stream rather than inventing a +success record. A hard kill, nonzero exit or missing final record is +**unverified cleanup**, even if an earlier startup record was emitted. The +provider supervisor must still verify and retire owned resources and descendants; +Python cannot cancel a blocked observer thread or infer that they exited from +the DHT's local return. Focused offline tests cover blocked startup/final +publication, stdout backpressure and a stopped child process. All 21 focused +cases passed in a local network-none Linux Python 3.12.13 container, including +the real full-pipe and process-group kill cases. DHT lifecycle cases use component +doubles. The +[image recipe](modal/Dockerfile.communityai-runtime) requires an immutable +Python/compiler/build-tools image and a coherent locked source context. +Its current source context is [PR40](https://github.com/flujo-app/CommunityAI/pull/40) +revision 681deb528a2d83a354a991a032c6ffa8d14a4242, stacked on PR38's +receiver and API lock repair. Direct server/text-peer roles accept a strict +`artifact_root` and separate writable `cache_dir`; missing, corrupt, linked or +undeclared inputs reject before model construction. The owner reports 110 +selected offline tests passed, and an independent reviewer reports 42 snapshot +tests passed. Hosted model CI was deliberately skipped. This direct interface +does not propagate through `drift node`. Dependency metadata and the lock are +byte-identical to PR38. A local compiler image has +been built with Python 3.12.13 and a retained tool/package inventory; its first +Debian package resolution was floating. The full local role image was built from +the locked source, with 101 compatible packages. Real runtime imports and all +four role help commands passed in a network-none container. Its retained local +image ID is +`sha256:07fe68fbe314f5ff0bcc3ed1dd82c6644af0253bb0ee0ad410489ea1c77df405`. +That retained image uses PR38 and lacks PR40's artifact-root interface. A new +local PR40 image is built and checked at +`sha256:af68ccf4c80b9939467d7e4d4ce2198bea16aedfd2a945bccce9eef093b31116`. +All 246 copied source files matched the exact prepared Git context; runtime +imports and four help commands passed with networking disabled. The original +image and its separate Linux/TLS evidence remain retained. +Separate retained qualification matches BuildKit's compiler material to the +inspected rootfs chain and records the compiler tag's configuration ID before +and after the build. Those local observations do not establish an immutable +compiler reference. Registry portability remains unqualified. + +The [local preparation helper](modal/prepare_communityai_local_image.py) exports +the recipe and Factory runtime files from exact committed Git blobs, preserving +the manifest's raw hash across dirty or CRLF checkouts, and records the complete +context. The +[local build helper](modal/build_communityai_local_image.py) rejects changed, +added, removed or linked context inputs, reserves its build intent exclusively, +and retains the output configuration ID, metadata hash and BuildKit reference +before compiler qualification. Receipt updates use flushed atomic replacements, +so interrupted writes leave the previous complete intent or PID record readable. +Uncertain builds cannot replay. Legacy +qualification requires a separately retained metadata witness and preserves the +original receipt; the caller must establish that witness's historical origin. +Eight fake-Docker provenance, concurrency and interruption checks passed. The +[import smoke](modal/smoke_communityai_local_image.py) checks imports and help +commands without starting roles. + +The current recipe copies only the pinned project metadata and lock before +dependency sync, then copies Python source. An actual network-none uv dry-run +accepted that exact metadata without README or source. This lets subsequent +source-only edits retain the dependency layer after the first build with this +ordering; a cache hit or build-speed gain has not been measured. The existing +image above retains its original recipe and evidence. New preparations must +select the exact reviewed recipe commit with required `--factory-commit`. +The export includes the launch-contract module imported by the bootstrap. + +All eight declared artifacts already present in the local Hub cache passed full +size/SHA verification and were copied into a separate plain-file snapshot. +The 4,079,422,995 copied bytes passed an independent rehash; the source cache +was unchanged and no download or model execution occurred. The +[snapshot smoke](modal/smoke_communityai_snapshot.py) then passed in the new +image: all eight files were hashed on an actual read-only mount, `blocks.lock` +was created in separate writable scratch, and eight actual worker/text-loader +constructors rejected missing, corrupt, extra and linked inputs. The container +exited zero and was removed. No model loaded or inference ran. Remote Volume, +registry image mapping and GPU/runtime qualification remain pending. + +Two real DHT nodes in that image then exchanged one exact short-lived value +over loopback with both p2pd processes configured for TLS. Each same DHT instance +shut down once with exit zero; the owned container exited zero and was removed. +A Torch shared-memory manager remained in the snapshot before parent exit, +explicitly recorded as unverified descendant cleanup. The smoke used a different +import order from the bootstrap role and proves local transport only. +Remote model cache qualification, Modal tunnel reachability, distributed model inference +and provider retirement remain unverified. Recursive provisioning and live +queue-driven scale-to-zero also remain subsequent integration work. + +The [host supervisor](modal/COMMUNITYAI_SUPERVISOR.md) now journals exact Modal +role resources, retains Sandbox IDs and actual raw TCP sockets, and fences +uncertain mutations against replay. Per-role OS locks protect observations and +checkpoint updates; terminal retirement evidence survives later running polls, +and retired roles cannot launch. Its four-role batch and model-worker/text exec +are explicitly held before paid creation or driver work. The local image and +snapshot checks above do not qualify the remote mounted artifacts, model runtime +or its paid/admission authority. Standalone +bootstrap lifecycle still requires explicit owner admission, existing hydrated +handles and budget authority. The exact model index now travels through the held +Node/Python carrier without a runtime fallback. Fourteen Node and twenty-one +Python driver checks pass in the main workspace on fresh owned fixtures and +SDK/driver doubles; the isolated full planner/driver suite passed 38 Python +checks. An actual owner bridge, verified remote cache, registry image mapping, +remote Original coordinator authority and live +distributed inference remain required. + +The original FACTORY controller remains paused with its $100 fully held, +$0 unallocated and final spending unknown. The new cloud lane keeps separate +ownership; its observations do not reset the original journals or reservations. + +An opt-in existing-worker power slice records owned Fly sleep/wake effects on the +original controller and shared paid ledger. Sleeping and unresolved workers fence +native dispatch; wake retains a separate spending allowance. Explicit native-cell +queue power scheduling now selects idle sleep or demand wake through that same +authority, with 87 focused local checks passing. The deployed native CLI now +accepts an explicit private powerScheduling profile; eight fake-transport CLI +checks pass, including restart, UNKNOWN and paid-zero cases. Live Fly and new +image qualification remain open. See [WORKER_POWER.md](WORKER_POWER.md) and +[NATIVE_CELLS.md](NATIVE_CELLS.md). + +The local model-step journal retains an immutable witness for each logical claim. +Unclaimed or missing model steps cannot satisfy parent completion, and retries +observe the original claim after interruption. The focused five-file capture passed +**129/129**, including 49 journal cases, and independent review accepted the exact +local adoption at `13d590f83aa9dc856ef1981b794f6dc1523943ab`. See +[the journal guide](MODEL_STEP_JOURNAL.md) and +[the next offline FLUJO bridge plan](FLUJO_OWNER_BRIDGE.md). Original live migration, +physical sending and provider admission remain held. + +The controller records missions, delegated allocations, cells, task ownership, +candidate reviews, messages and external-effect receipts in SQLite. The gateway +admits an effect before dispatch and preserves uncertainty across interruption. +Adapters reuse local Git and the existing `flujo-cloud` `ManagedCloud` service. + +The live Fly pilot passed with two real FLUJO workers, independent candidate +review and verified owned retirement. A real source-pinned FLUJO API documentation +task also passed independent review and local Git delivery from fresh upstream. +An isolated native FLUJO outcome repair then passed **213/213** targeted checks, +type checking, lint, separate acceptance and local Git delivery. It prevents +replayed Activities from corrupting Behavior outcome measurements; see +[NATIVE_OUTCOME.md](NATIVE_OUTCOME.md) for exact source, evidence and limits. +The deterministic recovery pilot uses real local processes, SQLite and Git with +fixed code fixtures. Modal inference and Modal-backed native Flow proof remain open: R3's +original v2-cache prefetch reached its bridge bound with an unknown outcome; +owned App/Volume cleanup and a fresh provider absence witness then completed. +All four paid reservations are `retired-meter-pending`, retaining the full $100 +with $0 unallocated. Recorded observations conservatively round to 30 cents; +they are neither exact total spend nor a strict monetary lower bound. Final spend +remains unknown and no new paid run is admitted. See +[QUALIFICATION.md](QUALIFICATION.md) for evidence and remaining work. + +Source `d9d87c6ebbd05b6c82bdbf0f7c537e76eb4b9a66` repeats shared paid-admission checks after awaited +stage notifications and FLUJO source discovery, immediately before paid SDK, +direct HTTP or Flow dispatch. Its complete Node 24 suite passed **461/461** and +focused Modal checks **36/36**. Separate retained-evidence qualification accepts +the actual closed run while preserving its failed raw collector receipt. Owned +cleanup and GET recovery of an original generation remain available while paid +admission is paused. This is local source qualification; mounted Modal weights, +GPU startup, Modal-backed native Flow and deployed autonomy remain open. + +Earlier source `72aec7cd64ff7d55ba8c7cb31bf371dee8a88044` adds explicit budget-only growth: +factory policy schema 2 removes cell-count and delegation-depth ceilings, and +capacity grant schema 2 removes its child-count ceiling. Parent allocations, +lifetime grant monetary ceilings and the shared SpendingLedger still constrain +admission. The complete suite passed **456/456** and the focused suite **60/60**. +Actual Docker capture/restore and schema-2 broker refusal/restart passed against +a fully held fixture budget. The original controller now uses budget-only policy, +paused at epoch 5 and revision 92. Its mission, budget and historical records +were preserved; the same loaded API served the transition. See +[the growth guide](BUDGET_GROWTH.md) for the exact policy and +trusted local migration commands. + +Source `fea3d151c1a4380495094744d00a33770b1abbb5` packages native-cell and +capacity-broker roles over one private authority. The full suite passed +**433/433**; the later fixture-only correction passed separate final-image +Docker acceptance. An authenticated container source exported its workspace, +and a second native worker restored its configuration with due schedules dormant. +Both workers exposed the expected MCP tool without invoking it. A fully held +fixture budget refused provisioning and broker restart preserved the original +`not_applied` intent. Separate native-cell acceptance retained one POST and one +synthetic-model call across lost-response restart and paused GET recovery. +All owned test resources were removed. See [the service guide](deploy/factory-service.md) +and [capacity broker guide](deploy/factory-service.broker.md). Paid inference, +cloud enrollment, shared remote authority and independent-host recovery remain open. + +Source `8ef36348f04d0a4a452acd75c493fb1cffa3c97c` adds the native cell mission queue. Its complete isolated +Node 24.19.0 suite passed **408/408**; the focused combination passed **50/50**. +Separate acceptance used actual daemon and FLUJO processes: new work arrived +after startup, a completed response was lost, both processes restarted, and +GET-only recovery succeeded while paused. Exactly one POST and one fixture-model +call occurred. A fully held fixture budget left the next task ready. All three +daemon processes and both native workers closed. This is local execution proof; +deployed autonomy, shared remote authority and paid Modal inference remain open. +See [NATIVE_CELLS.md](NATIVE_CELLS.md). + +Source `a05ae09e7faeba40d8d24470a924cf9e4b4b5f49` adds assigned native missions: +authenticated child preparation, atomic enrollment/task claim, one durable Flow +dispatch and recovery of the original result. The complete source suite passed +**383/383**. Separate acceptance restored a fresh native child, dropped its +completed response, restarted controller and worker, and recovered with exactly +one POST and one fixture-model call. Both actual workers closed. The software +task still requires independent review and delivery. This is local native +execution proof with a provisioning fixture; cloud autonomy and Modal inference +remain open. See [NATIVE_MISSIONS.md](NATIVE_MISSIONS.md). + +Source `56a2048485525e369a30e95e36c86397eea2b5ab` connects a native FLUJO Flow +to bounded child-capacity requests through a private MCP tool, authenticated +peers and a trusted standing-grant broker. Child allocation, lifetime grant +quota and provisioning intent commit together; actual SpendingLedger admission +precedes ManagedCloud dispatch. Exact replay never relaunches an intent. +The complete combination passed **358/358**. A fresh encrypted native worker +executed two real Flow/MCP requests using a synthetic loopback model: one +injected provision survived lost-ACK/store/process recovery without a second +dispatch, and the next request was refused against a fully held fixture budget. +All native workers closed. This proves local native request admission; deployed +child enrollment/autonomy and paid inference remain open. See +[NATIVE_CAPACITY.md](NATIVE_CAPACITY.md). + +Source `a283701933710bf39ea0673ab661064586e200f8` adds authenticated advisory +peer messages with a durable outbox/inbox, fixed destinations, credential +generations and private setup recovery. Its **11/11** focused checks include a +real receiver exit after inbox commit but before acknowledgement, both-process +restart, and retry resolving one original outbox with one inbox record/event. +The exact ten new files were adopted with all 54 existing runtime pins unchanged. +A subsequent actual pilot used two local CLI gateways to exchange authenticated +controller, paid-budget and Modal-journal observations in both directions. Each +store retained one acknowledged outbox and one inbox; both gateways closed with +the 64 source and 29 accounting/history witnesses unchanged. The observations +describe persisted history. Deployed peers, independent-host recovery and +autonomous enrollment remain open. See [PEER_MESSAGING.md](PEER_MESSAGING.md). + +Source `26c8cc4637a8f89c2f4a83092cb5d35f735794fc` adds automatic authenticated +mutual watching through `peer watch`: each native process probes the other +peer's own read-only controller and paid projection, persists meaningful changes +and retries exact original advisory messages after interruption. The complete +combination passed **335/335**; actual two-process acceptance showed unchanged +poll silence, a native state change, a missing peer, both-process restart and +replay of one original message after a deliberately lost ACK. Local detection was +about one second and reciprocal recovery about 1.29 seconds in this trial. +It creates no control or spending authority. Independent-host deployment, native +enrollment, Modal GPU/native Flow and a development-speed comparison remain open. +See [PEER_MESSAGING.md](PEER_MESSAGING.md) and +[QUALIFICATION.md](QUALIFICATION.md). + +Source `5293cfb22adde92d64ac27e3441b9b43f1d881c4` adds explicit operation completion +and task cancellation. Completion requires an immutable operation contract and +exact recorded success receipts; cancellation preserves acceptance, candidate +and review history. Neither establishes reviewed software delivery. The complete +combination passed **324/324** with actual exit 0 and process closure. Adoption +matched six qualified files and preserved 63 untouched runtime files and all +29 accounting/history witnesses. A rehearsal cancelled the original launch task +on a private database copy only. The separate growth-policy transition advanced +the live controller to revision 92 and paused epoch 5; that task remains running. +At the 15:16 UTC reconciliation, the original port 4344 API served build +`8f5a940`. A fresh 17:26 UTC process/listener inspection found its PID 52524 absent +and no listener on port 4344. A separate **18:35 UTC** read-only reconciliation +verified the single replacement **PID 29756** on `127.0.0.1:4344`, serving qualified +runtime `d9d87c6ebbd05b6c82bdbf0f7c537e76eb4b9a66`. Authenticated snapshot, events +and Modal-journal GETs returned 200/no-store; anonymous requests returned +401/no-store. The original launcher receipt remains failed after its Windows +argument-parser check; the separate reconciliation verified the existing process +without another launch or cleanup. Controller epoch 5/revision 92, paid revision +19, all original SQL histories and source bytes stayed unchanged. Commands remain +disabled. Brain's reader source is qualified; active O readers still need +qualification before any later live terminal transition. See [LIFECYCLE.md](LIFECYCLE.md) and +[QUALIFICATION.md](QUALIFICATION.md). + +Source `ac8b51fbf2833d347a0d96ed7f422a0bd82412bc` rejects invalid HTTP +continuations before the pinned Hub SDK appends bytes, including across redirects +and native retries. It binds an exact guard identity to new Modal intents and +receipts while preserving original cleanup. Its complete source combination +passed **302/302** on Node 24.19.0, including genuine tiny-body SDK probes and +the existing controller, budget and peer tests. Source adoption preserved all +57 untouched runtime files and 29 accounting/history files. This is local +qualification; mounted Modal weights, GPU startup and native Flow remain open. + +Source commit `0948fdd9ff7f5d379982e6e7286fd220236a1993` adopts the independently +reviewed logical lifecycle subset and low-memory HTTP preparation. The combined +188/188 qualification ran once in its isolated stage; adoption matched those +source bytes after line-ending normalization without another suite at that +adoption. The +HTTP download variant has not run in the cloud. Logical closure is implemented +for task release and never-provision-bound leaf cells. Later source `8dce857` +adds the narrow qualified provider-bound path described below. The historical port 4343 API used build `6fcd718` for the +Fly controller; that endpoint was subsequently observed unreachable. + +Source `67997585baa897bd7586fe21b9a755c89739a1a3` adds authenticated, read-only +Modal journal observation with private operator configuration and independent +content revisions. Its full combination passed **270/270**, exit 0, with unchanged +source during execution. A separate local API on port 4344 projected all three +actual journals and their 15 operations without changing their database/WAL bytes +or paid accounting. All three prefetch outcomes remain unknown. This view reports +persisted history rather than fresh provider status and does not establish model +inference or native Flow success. See [MODAL_OBSERVATION.md](MODAL_OBSERVATION.md) +for its separate contract and [QUALIFICATION.md](QUALIFICATION.md) for the exact +test and live-witness records. + +Source `8f5a94048e9c8be007cf3b5229607783b49cd47f` fixes the pinned vLLM startup +flag and adds complete artifact verification, private source/receipt binding and +read-only source preflight before paid resource admission. Its frozen combination +passed **274/274**, with matching source and historical paid-state bytes before +and after the final run. Earlier unstable/interrupted qualification attempts are +preserved separately. GPU boot, inference and native Flow remain unproven; +local artifact bytes were subsequently validated as described below. See the +[model definition](modal/README.md) and +[qualification record](QUALIFICATION.md). + +Actual local pinned-weight preparation passed after a reviewed resume. A separate +process independently validated all **13 files / 15.24 GB** in **61.60 seconds**, +with **30.8 MiB** peak memory. Both operations closed successfully and preserved +the protected source, history and owner state. This admits no new paid cloud work. See +[LOCAL_MODEL_PREPARATION.md](LOCAL_MODEL_PREPARATION.md) for its current evidence +and the separate remaining Modal/GPU/Flow requirements. + +The read-only API was restored on `127.0.0.1:4344` at build `8f5a940`; an actual +authenticated check again returned three journals and 15 operations without +changing their contents or paid accounting. The old port 4343 endpoint was not +restored. A brain-online adapter pinned to its old endpoint/build needs a reviewed +configuration update before using the restored service. + +Source `8dce857df549f29c69e566fa7d927196cb324c3c` adds provider-bound logical +leaf closure from recorded owned Fly teardown and a fresh configured-credential +inventory. Its complete frozen suite passed **288/288** and independent source +and outcome audits passed. The original child/parent worker cells are now retired +at controller events 90/91, preserving reviewed work and the unfinished root launch +task. Root logical capacity returned by $60 once; paid revision 17 still holds all +$100. Actual API checks project the new state under its existing loaded build +`8f5a940`. Physical quiescence and final billing remain unverified. See +[LIFECYCLE.md](LIFECYCLE.md) and [QUALIFICATION.md](QUALIFICATION.md). + +## Run locally + +Requirements: Node.js **24 or newer**, Git on `PATH`, and a local filesystem for +the controller database. There are no npm runtime dependencies to install. + +The full test suite additionally needs Python and the installed Modal SDK for +its definition checks. The genuine HTTP probes require explicit +`FACTORY_PYTHON`, `FACTORY_HUB_SITE` and `FACTORY_PRIVATE_MODULE` inputs: an +absolute base interpreter, owned site-packages containing Hub 0.36.0 and Requests, +and the trusted private-files module. Missing inputs fail rather than skip. +See [the Modal test instructions](modal/README.md) for the isolated probe scope. +Set these inputs before the complete test commands below. + +From this directory, with a suitable default Node: + +```powershell +node scripts/run-tests.mjs +node scripts/pilot.mjs .\evidence\local-pilot-01 +``` + +Use a fresh output directory for each deterministic pilot. The script preserves +its repository, controller database, candidate/review files, reconciliation +evidence and `report.json`; it deliberately does not reuse an existing fixture. + +The bundled runtime available on this machine is: + +```powershell +$factoryNode = 'C:\path\to\node.exe' +$env:FACTORY_PYTHON = 'C:\path\to\python.exe' +$env:FACTORY_HUB_SITE = 'C:\path\to\venv\Lib\site-packages' +$env:FACTORY_PRIVATE_MODULE = 'C:\path\to\flujo-cloud\lib\private-files.mjs' +& $factoryNode scripts/run-tests.mjs +& $factoryNode scripts/pilot.mjs .\evidence\local-pilot-01 +``` + +`npm test` and `npm run pilot` use the default Node executable. Invoke the bundled +executable directly when the default installation is older than Node 24. + +## What the deterministic pilot checks + +The pilot creates two candidate branches from one baseline. A separate evaluation +process accepts the correct implementation and rejects the competing fixture. A +single integration owner admits the accepted candidate's exact target, baseline +and commit. + +The delivery subprocess then updates a real Git reference and exits before its +receipt is saved. A fresh controller observes the unresolved effect, refuses +takeover, inspects the actual Git reference and records reconciliation. It marks +the task delivered, grants a successor ownership epoch, rejects stale authority +and finishes with admission paused. + +The accompanying tests exercise concurrent processes sharing the SQLite database, +allocation conservation, duplicate identities, ownership fencing, candidate and +review binding, private result artifacts, receipt/finalization replay and atomic +Git compare-and-swap. The branch builders are deterministic fixtures; the pilot +does not measure model-generated development speed or improve production FLUJO. + +Read `report.json` for the evidence scope and result. `state.json` is an operational +snapshot; the SQLite database is the authoritative record. + +## Controller CLI + +```powershell +node bin/factory.mjs +``` + +Commands that need input read one JSON object from standard input. For example: + +```powershell +$factoryDatabase = Join-Path (Get-Location) '.factory\controller.sqlite' +'{"mission":"Improve FLUJO development speed","budgetCents":10000,"maxCells":5,"maxDepth":2}' | + node bin/factory.mjs init $factoryDatabase +node bin/factory.mjs status $factoryDatabase +node bin/factory.mjs pause $factoryDatabase +node bin/factory.mjs resume $factoryDatabase +``` + +Replace `node` with `& $factoryNode` when using the bundled runtime. + +| Command | JSON input | +| --- | --- | +| `init` | `mission`, `budgetCents`; legacy optional `maxCells`, `maxDepth`, or explicit `growthMode: "budget-only"` | +| `status`, `pause`, `resume` | No input | +| `growth-policy` | No input; read existing policy, epoch, status and policy digest | +| `budget-growth` | `transitionId`, `expectedFactoryEpoch`, `expectedPolicyDigest`; existing paused authority only | +| `reserve` | `cellId`, `budgetCents`, `purpose`; optional `parentId`, `role` | +| `enroll` | `cellId` | +| `task` | `taskId`, `projectId`, `branch`, `specification` | +| `claim` | `taskId`, `cellId`; optional `ttlMs` | +| `integration` | `projectId`; optional `cellId`, `ttlMs` | +| `message` | `sender`, `messageId`, `recipient`, `payload`; optional `taskId`, `attempt` | +| `inbox` | `cellId` | + +A task specification names `problem`, `acceptance` and `baseline`. Git delivery +also pins `deliveryTarget: {repository, ref}`. The reviewed candidate artifact +records `{repository, ref, baseline, candidateHead, branch}`; admission binds the +delivery request to those bytes. + +Lease responses contain private runner capability tokens. Keep them in +owner-private runner storage and exclude them from public reports. The CLI is a +trusted local operator interface. Worker authentication over HTTP, remote +enrollment and cross-host consensus are future work. + +## State, pause and recovery + +`control.status: active` permits admission; it does not mean workers have started. +`paused` revokes new admission and advances the control epoch. `resume` advances +it again, so old leases remain stale. + +`effectsDrained` means the ledger has no accepted, running or unknown effects. +`workerQuiescence: unverified` means the controller has not established that every +worker/process has stopped. A paused controller can still have an admitted effect +finishing or an unresolved external outcome. This pilot does not stop unrelated +Codex chats, automations or processes. + +An effect's stable key and request digest identify its intent. Matching receipt +replay and delivery finalization preserve the original result without dispatching +again or recording a second completion. A different request or ownership attempt +cannot reuse that key. + +After interruption, inspect the existing task, effect and destination before +retrying. A timeout does not prove an operation failed. Unresolved effects block +conflicting takeover. An accepted intent that never started can be cancelled; +negative reconciliation of a started or unknown effect is deliberately +unsupported without executor proof. The local Git pilot demonstrates positive +reconciliation of an observed exact commit. `executeGitDelivery` in +`src/git-effect.mjs` adds a narrow exception for a completed, genuine local Git +compare-and-swap refusal: it settles as `not_applied` using a bound, single-use +in-process proof. A timeout, killed executor, forged error or missing receipt +still remains unknown. Refusal leaves the reviewed task undelivered; rebasing +requires a new candidate and review. + +Preserve the controller database and recovery artifacts. For cloud operations, +also preserve `ManagedCloud` attempt metadata, journals and credentials until +owned retirement is confirmed. A new worker name is a new deployment, not a +recovery of the previous uncertain attempt. + +## Read-only cloud preflight + +The preflight script verifies an explicitly selected native source, reads +workspace/configuration metadata and checks compatible official-image selection. +It creates no deployment and runs no Flow. + +```powershell +node scripts/cloud-preflight.mjs ` + --module-path 'C:\path\to\flujo-cloud\lib\managed.mjs' ` + --source 'http://127.0.0.1:4200' ` + --workspace 'factory-pilot' +``` + +Use the actual registered source origin. Exit code `0` means compatible image +selection was confirmed; `2` means selection was unconfirmed or the workspace was +absent; `1` means the preflight itself could not be confirmed. This is preparation +evidence, not a running-worker acceptance result. + +## Isolated live pilot operation + +The spending intent is **at most US$100 across the paid cloud work**, including +the Modal/open-weight model path. `src/spending.mjs` conserves one durable USD +allowance across providers, using integer cents and serialized admission. The +first experiment reserved $10 for Fly and $30 for Modal. Two further, distinct +Modal experiments each hold $30; all $100 is reserved and $0 remains unallocated. Current +results and billing status are recorded in [QUALIFICATION.md](QUALIFICATION.md). +All four reservations are now retired pending final billing, with the full holds +unchanged. The latest paid revision is 19; its 30 recorded cents are conservatively +rounded partial observations, not exact total spend. No fresh paid experiment is +admitted by the source update. +Each paid dispatch rechecks its reservation; known experiment or global exhaustion +blocks new paid work. Owned cleanup remains possible. Retirement keeps funds held +until final billing evidence arrives; it cannot release uncertain charges. The +ledger covers registered factory spending, not unrelated provider-account costs. + +The local `budgetCents` and child +allocations conserve delegated budget; they do not meter actual compute, +inference, storage or provider charges and are not a provider-side billing stop. +An experiment needs explicit resource/time limits and observed cleanup as well as +budget records. Overall factory work has no time limit; the limits below apply to +this first Fly experiment. + +The initial live slice is bounded to **two temporary cloud workers**, delegation +depth **two**, Flow-call timeout **180 seconds**, and a **15-minute work deadline**. +It uses a dedicated `factory-pilot` workspace with a minimal Flow and no attached +MCP tools. The first worker produces a bounded function candidate and a +schema-validated child request. The local coordinator admits and provisions that +child from its parent's allocation. The child returns a JSON review, and the local +verifier checks the candidate's exact pure-function grammar and fixed acceptance +table. Generated code is preserved as an artifact and is never executed locally. + +The work deadline bounds new admission and individual HTTP/Fly commands. It does +not guarantee a global cancellation or shutdown time. Owned cleanup has a separate +five-minute command deadline. + +The live runner prepares read-only unless `--execute` is supplied: + +```powershell +$cloudPilotDirectory = Join-Path (Get-Location) '.factory\cloud-pilot-01' +node scripts/cloud-pilot.mjs ` + --run-id 'cloud-pilot-01' ` + --output $cloudPilotDirectory ` + --module-path 'C:\path\to\flujo-cloud\lib\managed.mjs' ` + --source 'http://127.0.0.1:4200' +``` + +Use the registered native source origin. Add `--execute` and +`--spending-ledger` with the absolute path of the shared `.factory\spending.sqlite` +to this same invocation +to run the isolated pilot. The runner refuses to adopt an existing fixture +workspace. An existing manifest returns `observe-existing` without reprovisioning +or replaying model calls; inspect its original attempts before further recovery. +Exit code `2` means the live proof failed or an existing run needs reconciliation. +An explicit `--resume-fixture` is limited to the original pre-cloud fixture +failure: original source/image/manifest, empty owned workspace creation proof, +fixed model/Flow inventory, paused controller and zero historical effects are +required. Recovery preserves its old report and app identities. It is not a +general cloud retry. +The runner verifies that the source's default agent uses the approved +`gpt-6-astra / codex / codex-cli` model tuple; it does not change that source +binding. The dedicated source workspace remains available for inspection after +cloud retirement. + +This qualifies gateway-mediated delegation if it succeeds. Native autonomous +child provisioning, cross-host ownership, mutual monitoring, source branch +development and fleet learning each still need their own proofs. + +Owned retirement belongs in the runner's `finally` path and uses a narrow trusted +local cleanup authority. That authority can retire an app while admission is +paused only when the app is bound to this controller's original provisioning +intent. It cannot grant a general work lease or resume dispatch. Retirement +identity validation requires the matching app and a terminal destroyed result; +uncertain cleanup remains unresolved and cannot be blindly retried under another +key. Existing unresolved work records remain intact. + +`ManagedCloud.down` verifies the deployment's journal and cloud ownership before +deleting its dedicated application. A failed or uncertain retirement must remain +visible with its original identities and recovery records. Deadline expiry alone +is not evidence that a resource was retired; recovery must inspect and reconcile +it. A separate same-host watcher can record heartbeat, ledger and live provider +observations; it cannot grant ownership, retire resources or recover from loss of +the host itself. + +For an observation after the manifest and controller ledger exist: + +```powershell +node scripts/watch-pilot.mjs ` + --manifest (Join-Path $cloudPilotDirectory 'manifest.json') ` + --module-path 'C:\path\to\flujo-cloud\lib\managed.mjs' ` + --fly-path 'C:\path\to\flyctl.exe' ` + --once +``` + +Use the actual absolute Fly executable path. Without `--once`, the watcher runs a +bounded observation loop. It records provider evidence in +`watch-observations.jsonl` and can send structured observations to the local root +inbox. A witness of app absence is stronger than cached inventory; it still does +not establish metered spend or full worker quiescence. If the coordinator dies, +the witness can report that condition but cannot perform teardown. + +### Source and image boundaries + +The existing shared FLUJO checkout is dirty; its checkout and running build were +preserved. The one-file API documentation task used a fresh isolated worktree at +upstream `d68492712315d30c856c8d2ba95b0a26a859bd18`. Independent review accepted +candidate `ea66f1130e01d3208173cd850d40f85f319b3582`, and the reviewed local target +`refs/heads/codex/factory-reviewed-api-token-limit-docs` received that exact commit +through Git compare-and-swap. This corrected HTTP versus authored Flow token-limit +documentation; it created no PR, push, upstream merge or runtime change. Runtime +FLUJO improvements and upstream publication still require their own acceptance. +The task's `docs-builder` and `docs-reviewer` cells were then logically retired +using the qualified controller subset. Independent audit confirmed the exact +closure events, preserved delivered work and unchanged billing records. +Provider/process quiescence remains unverified. + +The cloud bridge snapshots durable workspace state from a running native source +and selects a compatible immutable worker image. Application-version or channel +fallback establishes the declared compatibility contract; it does not establish +equality with an unreported or dirty local Git checkout. Preserve the selected +source, snapshot and image identities in live evidence. + +Flow selection controls startup/call scope and does not redact unrelated +workspace data or credentials. Use the dedicated workspace to constrain the +transferred contents. Copied model authentication and shared provider accounts +also retain common failure dependencies; two cloud workers do not by themselves +prove independent authentication or inference availability. + +## Current limits + +- One local SQLite authority; no distributed failover or consensus qualification. +- Trusted local processes and filesystem; worker isolation and gateway-only + external credentials need separate enforcement. +- One real isolated documentation delivery and deterministic recovery fixtures; + no unattended roadmap execution or measured factory self-improvement. +- Logical watcher/cell/message records; no independently hosted watchdog is + established by the local pilot. +- Provisioning adapter over existing `ManagedCloud`; the bounded Fly deployment, + model calls and owned cleanup passed. General remote-result reconciliation, + automatic health recovery, runtime-source improvement and upstream publication + remain unqualified. diff --git a/QUALIFICATION.md b/QUALIFICATION.md index 370d8fd..7f78e91 100644 --- a/QUALIFICATION.md +++ b/QUALIFICATION.md @@ -872,7 +872,7 @@ logical allocation and paid admission projections. The brain-online staff BFF also read this actual endpoint successfully; anonymous access was rejected and customer access excluded. Its frontend work is [brain-online PR 34](https://github.com/flujo-app/brain-online/pull/34). -See [the interface contract](C:/Users/Moe/Documents/ChatGPT/FACTORY/BRAIN_ONLINE_INTEGRATION.md). +See [the interface contract](BRAIN_ONLINE_INTEGRATION.md). This snapshot's task/effect/pause scope is the Fly pilot's controller. Modal uses a separate operation journal and shared paid-admission ledger, without consulting diff --git a/README.md b/README.md index 8a990ac..b1d3db1 100644 --- a/README.md +++ b/README.md @@ -1,710 +1,180 @@ -# FLUJO factory pilot - -For the installable local SDK, CLI, and MCP server, see [Public Factory interfaces](PUBLIC_SDK.md). -For current cross-product adoption and release gates, see [Integration status](INTEGRATION_STATUS.md). -Factory is available under the [MIT License](LICENSE). - -The factory's first mission is to improve FLUJO, optimizing the time from an -accepted requirement to independently accepted delivery within quality and cost -constraints. This directory contains the first runnable **local coordination and -recovery pilot**. The larger design is in [FACTORY_DESIGN.md](FACTORY_DESIGN.md) and -[FEDERATION.md](FEDERATION.md). - -## October 4 priority - -Make the supervised WebUI → Fly FLUJO workers → private Modal route usable first. -Development that produces and checks code comes next; broad scorecards, -polishing and audit expansion wait. - -The existing cloud lane is owned by [Review linked Codex thread](codex://threads/01a0ff01-f462-7712-a465-eb234970f7e9). -Its [recorded acceptance](C:/Users/Moe/Documents/GitHub/iambrokeplshlp/artifacts/cloud-spike-live-acceptance-20261004.json) -establishes one supervised text job through two Fly workers using private -Ollama Qwen3 4B on Modal, followed by exact completed-job recovery after restart -with no inference replay. The developer gave an incorrect arithmetic answer -and the reviewer corrected it. FACTORY read the public receipt and recovery -contract; that recorded scope does not include code tools or income. - -Reuse that working gateway and worker lane. Root/Auth own its code executor. -FACTORY provides the supplied-task and immutable test/result receipt -contract in [src/development-job-contract.mjs](src/development-job-contract.mjs). -Its 14 focused tests pass. bindDevelopmentJob() freezes the task, candidate -file hashes, executor build and fixed Node test target; projectDevelopmentJob() -checks an independently pinned supplied receipt against that binding. A passing -receipt marks the proposal checked with explicitly unauthenticated provenance. -Applied code remains not_applied, income remains no_evidence and admission is -NO_ADMISSION; external sends require the named owner bridge. - -The working Python cloud executor has its own supplied-result contract in -[src/python-cloud-job-contract.mjs](src/python-cloud-job-contract.mjs). -bindPythonCloudJob() freezes the selected task and Python source hashes; -projectPythonCloudJob() checks the retained original request and response bytes -against the operation and fixed injected arithmetic or invoice suite. Its 17 -focused tests pass. The original runner response must retain trustedSuite, -trustedMinimum and trustedSuiteComplete; the current MCP text projection drops -those fields and cannot substitute for the raw receipt. Passing evidence yields -checked with unauthenticated runtime/suite provenance, NO_ADMISSION, -not_applied and no_evidence. The existing Node contract remains separate. - -The adapter also accepted a retained original cloud request and response for a -CSV job: ten project cases plus three fixed arithmetic cases, minimum three, -with cleanup confirmed. This was a local projection of saved bytes with no job -replay. Task and executor labels were supplied retrospectively; the actual -executor build remains unknown. Its checked result retains NO_ADMISSION and -not_applied. The earlier invoice fallback's original wire bytes were not retained -and were not reconstructed for this check. - -The cloud owner's [code acceptance record](C:/Users/Moe/Documents/GitHub/iambrokeplshlp/artifacts/cloud-native-code-acceptance-20261004.json) -reports a real three-test arithmetic run and a deterministic invoice fallback -that passed 13 CPU checks with cleanup confirmed. The generated invoice V5 -passed nine fixed cases but retains known whitespace/precision gaps. The phone -reviewer assessed text; independent code execution is a separate sandbox result. -FACTORY consumed that public record without replaying the job or inference. - -[modal/communityai_bootstrap.py](modal/communityai_bootstrap.py) now wires the -pinned Qwen3 1.7B manifest, two complementary block workers, a text peer and -the actual CommunityAI coordinator APIs. A supplied four-role formation retains -actual public TCP ports and application TLS; host admission and receiver -authentication must be supplied by its owner. The launch contract requires the -exact retained model index, derives both block selections and carries all five -worker consistency claims. Model files use a read-only declared snapshot; -locks and cache state use distinct writable directories for each role. -Forty-one focused checks passed in the combined main checkout, covering -planning, held lifecycle behavior and image export/build receipts. - -[modal/communityai_runtime.py](modal/communityai_runtime.py) adds the real TLS -DHT bootstrap entry point, actual public/listen port handling, one bounded -startup observation deadline, expiry/stop handling and cleanup without retry. -Lifecycle observer calls have a one-second return bound. A stalled startup -observer causes same-DHT shutdown and suppresses a concurrent final callback; -a stalled final observer is an error after shutdown. The retained record labels -both publication states, possible late daemon-thread side effects and unverified -descendant retirement. On Linux the CLI writes each small JSON record directly -to nonblocking stdout, so a full log pipe fails the publication instead of -holding the cleanup path. Callback return means only that publication code -returned; it does not prove external delivery. - -The [bootstrap watchdog](modal/communityai_runtime_watchdog.py) runs that CLI in -an isolated Linux process group, anchors the supplied expiry to a monotonic -deadline, requests stop and sends a hard kill if the child misses a seven-second -cleanup grace. It inherits the child's lifecycle stream rather than inventing a -success record. A hard kill, nonzero exit or missing final record is -**unverified cleanup**, even if an earlier startup record was emitted. The -provider supervisor must still verify and retire owned resources and descendants; -Python cannot cancel a blocked observer thread or infer that they exited from -the DHT's local return. Focused offline tests cover blocked startup/final -publication, stdout backpressure and a stopped child process. All 21 focused -cases passed in a local network-none Linux Python 3.12.13 container, including -the real full-pipe and process-group kill cases. DHT lifecycle cases use component -doubles. The -[image recipe](modal/Dockerfile.communityai-runtime) requires an immutable -Python/compiler/build-tools image and a coherent locked source context. -Its current source context is [PR40](https://github.com/flujo-app/CommunityAI/pull/40) -revision 681deb528a2d83a354a991a032c6ffa8d14a4242, stacked on PR38's -receiver and API lock repair. Direct server/text-peer roles accept a strict -`artifact_root` and separate writable `cache_dir`; missing, corrupt, linked or -undeclared inputs reject before model construction. The owner reports 110 -selected offline tests passed, and an independent reviewer reports 42 snapshot -tests passed. Hosted model CI was deliberately skipped. This direct interface -does not propagate through `drift node`. Dependency metadata and the lock are -byte-identical to PR38. A local compiler image has -been built with Python 3.12.13 and a retained tool/package inventory; its first -Debian package resolution was floating. The full local role image was built from -the locked source, with 101 compatible packages. Real runtime imports and all -four role help commands passed in a network-none container. Its retained local -image ID is -`sha256:07fe68fbe314f5ff0bcc3ed1dd82c6644af0253bb0ee0ad410489ea1c77df405`. -That retained image uses PR38 and lacks PR40's artifact-root interface. A new -local PR40 image is built and checked at -`sha256:af68ccf4c80b9939467d7e4d4ce2198bea16aedfd2a945bccce9eef093b31116`. -All 246 copied source files matched the exact prepared Git context; runtime -imports and four help commands passed with networking disabled. The original -image and its separate Linux/TLS evidence remain retained. -Separate retained qualification matches BuildKit's compiler material to the -inspected rootfs chain and records the compiler tag's configuration ID before -and after the build. Those local observations do not establish an immutable -compiler reference. Registry portability remains unqualified. - -The [local preparation helper](modal/prepare_communityai_local_image.py) exports -the recipe and Factory runtime files from exact committed Git blobs, preserving -the manifest's raw hash across dirty or CRLF checkouts, and records the complete -context. The -[local build helper](modal/build_communityai_local_image.py) rejects changed, -added, removed or linked context inputs, reserves its build intent exclusively, -and retains the output configuration ID, metadata hash and BuildKit reference -before compiler qualification. Receipt updates use flushed atomic replacements, -so interrupted writes leave the previous complete intent or PID record readable. -Uncertain builds cannot replay. Legacy -qualification requires a separately retained metadata witness and preserves the -original receipt; the caller must establish that witness's historical origin. -Eight fake-Docker provenance, concurrency and interruption checks passed. The -[import smoke](modal/smoke_communityai_local_image.py) checks imports and help -commands without starting roles. - -The current recipe copies only the pinned project metadata and lock before -dependency sync, then copies Python source. An actual network-none uv dry-run -accepted that exact metadata without README or source. This lets subsequent -source-only edits retain the dependency layer after the first build with this -ordering; a cache hit or build-speed gain has not been measured. The existing -image above retains its original recipe and evidence. New preparations must -select the exact reviewed recipe commit with required `--factory-commit`. -The export includes the launch-contract module imported by the bootstrap. - -All eight declared artifacts already present in the local Hub cache passed full -size/SHA verification and were copied into a separate plain-file snapshot. -The 4,079,422,995 copied bytes passed an independent rehash; the source cache -was unchanged and no download or model execution occurred. The -[snapshot smoke](modal/smoke_communityai_snapshot.py) then passed in the new -image: all eight files were hashed on an actual read-only mount, `blocks.lock` -was created in separate writable scratch, and eight actual worker/text-loader -constructors rejected missing, corrupt, extra and linked inputs. The container -exited zero and was removed. No model loaded or inference ran. Remote Volume, -registry image mapping and GPU/runtime qualification remain pending. - -Two real DHT nodes in that image then exchanged one exact short-lived value -over loopback with both p2pd processes configured for TLS. Each same DHT instance -shut down once with exit zero; the owned container exited zero and was removed. -A Torch shared-memory manager remained in the snapshot before parent exit, -explicitly recorded as unverified descendant cleanup. The smoke used a different -import order from the bootstrap role and proves local transport only. -Remote model cache qualification, Modal tunnel reachability, distributed model inference -and provider retirement remain unverified. Recursive provisioning and live -queue-driven scale-to-zero also remain subsequent integration work. - -The [host supervisor](modal/COMMUNITYAI_SUPERVISOR.md) now journals exact Modal -role resources, retains Sandbox IDs and actual raw TCP sockets, and fences -uncertain mutations against replay. Per-role OS locks protect observations and -checkpoint updates; terminal retirement evidence survives later running polls, -and retired roles cannot launch. Its four-role batch and model-worker/text exec -are explicitly held before paid creation or driver work. The local image and -snapshot checks above do not qualify the remote mounted artifacts, model runtime -or its paid/admission authority. Standalone -bootstrap lifecycle still requires explicit owner admission, existing hydrated -handles and budget authority. The exact model index now travels through the held -Node/Python carrier without a runtime fallback. Fourteen Node and twenty-one -Python driver checks pass in the main workspace on fresh owned fixtures and -SDK/driver doubles; the isolated full planner/driver suite passed 38 Python -checks. An actual owner bridge, verified remote cache, registry image mapping, -remote Original coordinator authority and live -distributed inference remain required. - -The original FACTORY controller remains paused with its $100 fully held, -$0 unallocated and final spending unknown. The new cloud lane keeps separate -ownership; its observations do not reset the original journals or reservations. - -An opt-in existing-worker power slice records owned Fly sleep/wake effects on the -original controller and shared paid ledger. Sleeping and unresolved workers fence -native dispatch; wake retains a separate spending allowance. Explicit native-cell -queue power scheduling now selects idle sleep or demand wake through that same -authority, with 87 focused local checks passing. The deployed native CLI now -accepts an explicit private powerScheduling profile; eight fake-transport CLI -checks pass, including restart, UNKNOWN and paid-zero cases. Live Fly and new -image qualification remain open. See [WORKER_POWER.md](WORKER_POWER.md) and -[NATIVE_CELLS.md](NATIVE_CELLS.md). - -The local model-step journal retains an immutable witness for each logical claim. -Unclaimed or missing model steps cannot satisfy parent completion, and retries -observe the original claim after interruption. The focused five-file capture passed -**129/129**, including 49 journal cases, and independent review accepted the exact -local adoption at `13d590f83aa9dc856ef1981b794f6dc1523943ab`. See -[the journal guide](MODEL_STEP_JOURNAL.md) and -[the next offline FLUJO bridge plan](FLUJO_OWNER_BRIDGE.md). Original live migration, -physical sending and provider admission remain held. - -The controller records missions, delegated allocations, cells, task ownership, -candidate reviews, messages and external-effect receipts in SQLite. The gateway -admits an effect before dispatch and preserves uncertainty across interruption. -Adapters reuse local Git and the existing `flujo-cloud` `ManagedCloud` service. - -The live Fly pilot passed with two real FLUJO workers, independent candidate -review and verified owned retirement. A real source-pinned FLUJO API documentation -task also passed independent review and local Git delivery from fresh upstream. -An isolated native FLUJO outcome repair then passed **213/213** targeted checks, -type checking, lint, separate acceptance and local Git delivery. It prevents -replayed Activities from corrupting Behavior outcome measurements; see -[NATIVE_OUTCOME.md](NATIVE_OUTCOME.md) for exact source, evidence and limits. -The deterministic recovery pilot uses real local processes, SQLite and Git with -fixed code fixtures. Modal inference and Modal-backed native Flow proof remain open: R3's -original v2-cache prefetch reached its bridge bound with an unknown outcome; -owned App/Volume cleanup and a fresh provider absence witness then completed. -All four paid reservations are `retired-meter-pending`, retaining the full $100 -with $0 unallocated. Recorded observations conservatively round to 30 cents; -they are neither exact total spend nor a strict monetary lower bound. Final spend -remains unknown and no new paid run is admitted. See -[QUALIFICATION.md](QUALIFICATION.md) for evidence and remaining work. - -Source `d9d87c6ebbd05b6c82bdbf0f7c537e76eb4b9a66` repeats shared paid-admission checks after awaited -stage notifications and FLUJO source discovery, immediately before paid SDK, -direct HTTP or Flow dispatch. Its complete Node 24 suite passed **461/461** and -focused Modal checks **36/36**. Separate retained-evidence qualification accepts -the actual closed run while preserving its failed raw collector receipt. Owned -cleanup and GET recovery of an original generation remain available while paid -admission is paused. This is local source qualification; mounted Modal weights, -GPU startup, Modal-backed native Flow and deployed autonomy remain open. - -Earlier source `72aec7cd64ff7d55ba8c7cb31bf371dee8a88044` adds explicit budget-only growth: -factory policy schema 2 removes cell-count and delegation-depth ceilings, and -capacity grant schema 2 removes its child-count ceiling. Parent allocations, -lifetime grant monetary ceilings and the shared SpendingLedger still constrain -admission. The complete suite passed **456/456** and the focused suite **60/60**. -Actual Docker capture/restore and schema-2 broker refusal/restart passed against -a fully held fixture budget. The original controller now uses budget-only policy, -paused at epoch 5 and revision 92. Its mission, budget and historical records -were preserved; the same loaded API served the transition. See -[the growth guide](BUDGET_GROWTH.md) for the exact policy and -trusted local migration commands. - -Source `fea3d151c1a4380495094744d00a33770b1abbb5` packages native-cell and -capacity-broker roles over one private authority. The full suite passed -**433/433**; the later fixture-only correction passed separate final-image -Docker acceptance. An authenticated container source exported its workspace, -and a second native worker restored its configuration with due schedules dormant. -Both workers exposed the expected MCP tool without invoking it. A fully held -fixture budget refused provisioning and broker restart preserved the original -`not_applied` intent. Separate native-cell acceptance retained one POST and one -synthetic-model call across lost-response restart and paused GET recovery. -All owned test resources were removed. See [the service guide](deploy/factory-service.md) -and [capacity broker guide](deploy/factory-service.broker.md). Paid inference, -cloud enrollment, shared remote authority and independent-host recovery remain open. - -Source `8ef36348f04d0a4a452acd75c493fb1cffa3c97c` adds the native cell mission queue. Its complete isolated -Node 24.19.0 suite passed **408/408**; the focused combination passed **50/50**. -Separate acceptance used actual daemon and FLUJO processes: new work arrived -after startup, a completed response was lost, both processes restarted, and -GET-only recovery succeeded while paused. Exactly one POST and one fixture-model -call occurred. A fully held fixture budget left the next task ready. All three -daemon processes and both native workers closed. This is local execution proof; -deployed autonomy, shared remote authority and paid Modal inference remain open. -See [NATIVE_CELLS.md](NATIVE_CELLS.md). - -Source `a05ae09e7faeba40d8d24470a924cf9e4b4b5f49` adds assigned native missions: -authenticated child preparation, atomic enrollment/task claim, one durable Flow -dispatch and recovery of the original result. The complete source suite passed -**383/383**. Separate acceptance restored a fresh native child, dropped its -completed response, restarted controller and worker, and recovered with exactly -one POST and one fixture-model call. Both actual workers closed. The software -task still requires independent review and delivery. This is local native -execution proof with a provisioning fixture; cloud autonomy and Modal inference -remain open. See [NATIVE_MISSIONS.md](NATIVE_MISSIONS.md). - -Source `56a2048485525e369a30e95e36c86397eea2b5ab` connects a native FLUJO Flow -to bounded child-capacity requests through a private MCP tool, authenticated -peers and a trusted standing-grant broker. Child allocation, lifetime grant -quota and provisioning intent commit together; actual SpendingLedger admission -precedes ManagedCloud dispatch. Exact replay never relaunches an intent. -The complete combination passed **358/358**. A fresh encrypted native worker -executed two real Flow/MCP requests using a synthetic loopback model: one -injected provision survived lost-ACK/store/process recovery without a second -dispatch, and the next request was refused against a fully held fixture budget. -All native workers closed. This proves local native request admission; deployed -child enrollment/autonomy and paid inference remain open. See -[NATIVE_CAPACITY.md](NATIVE_CAPACITY.md). - -Source `a283701933710bf39ea0673ab661064586e200f8` adds authenticated advisory -peer messages with a durable outbox/inbox, fixed destinations, credential -generations and private setup recovery. Its **11/11** focused checks include a -real receiver exit after inbox commit but before acknowledgement, both-process -restart, and retry resolving one original outbox with one inbox record/event. -The exact ten new files were adopted with all 54 existing runtime pins unchanged. -A subsequent actual pilot used two local CLI gateways to exchange authenticated -controller, paid-budget and Modal-journal observations in both directions. Each -store retained one acknowledged outbox and one inbox; both gateways closed with -the 64 source and 29 accounting/history witnesses unchanged. The observations -describe persisted history. Deployed peers, independent-host recovery and -autonomous enrollment remain open. See [PEER_MESSAGING.md](PEER_MESSAGING.md). - -Source `26c8cc4637a8f89c2f4a83092cb5d35f735794fc` adds automatic authenticated -mutual watching through `peer watch`: each native process probes the other -peer's own read-only controller and paid projection, persists meaningful changes -and retries exact original advisory messages after interruption. The complete -combination passed **335/335**; actual two-process acceptance showed unchanged -poll silence, a native state change, a missing peer, both-process restart and -replay of one original message after a deliberately lost ACK. Local detection was -about one second and reciprocal recovery about 1.29 seconds in this trial. -It creates no control or spending authority. Independent-host deployment, native -enrollment, Modal GPU/native Flow and a development-speed comparison remain open. -See [PEER_MESSAGING.md](PEER_MESSAGING.md) and -[QUALIFICATION.md](QUALIFICATION.md). - -Source `5293cfb22adde92d64ac27e3441b9b43f1d881c4` adds explicit operation completion -and task cancellation. Completion requires an immutable operation contract and -exact recorded success receipts; cancellation preserves acceptance, candidate -and review history. Neither establishes reviewed software delivery. The complete -combination passed **324/324** with actual exit 0 and process closure. Adoption -matched six qualified files and preserved 63 untouched runtime files and all -29 accounting/history witnesses. A rehearsal cancelled the original launch task -on a private database copy only. The separate growth-policy transition advanced -the live controller to revision 92 and paused epoch 5; that task remains running. -At the 15:16 UTC reconciliation, the original port 4344 API served build -`8f5a940`. A fresh 17:26 UTC process/listener inspection found its PID 52524 absent -and no listener on port 4344. A separate **18:35 UTC** read-only reconciliation -verified the single replacement **PID 29756** on `127.0.0.1:4344`, serving qualified -runtime `d9d87c6ebbd05b6c82bdbf0f7c537e76eb4b9a66`. Authenticated snapshot, events -and Modal-journal GETs returned 200/no-store; anonymous requests returned -401/no-store. The original launcher receipt remains failed after its Windows -argument-parser check; the separate reconciliation verified the existing process -without another launch or cleanup. Controller epoch 5/revision 92, paid revision -19, all original SQL histories and source bytes stayed unchanged. Commands remain -disabled. Brain's reader source is qualified; active O readers still need -qualification before any later live terminal transition. See [LIFECYCLE.md](LIFECYCLE.md) and -[QUALIFICATION.md](QUALIFICATION.md). - -Source `ac8b51fbf2833d347a0d96ed7f422a0bd82412bc` rejects invalid HTTP -continuations before the pinned Hub SDK appends bytes, including across redirects -and native retries. It binds an exact guard identity to new Modal intents and -receipts while preserving original cleanup. Its complete source combination -passed **302/302** on Node 24.19.0, including genuine tiny-body SDK probes and -the existing controller, budget and peer tests. Source adoption preserved all -57 untouched runtime files and 29 accounting/history files. This is local -qualification; mounted Modal weights, GPU startup and native Flow remain open. - -Source commit `0948fdd9ff7f5d379982e6e7286fd220236a1993` adopts the independently -reviewed logical lifecycle subset and low-memory HTTP preparation. The combined -188/188 qualification ran once in its isolated stage; adoption matched those -source bytes after line-ending normalization without another suite at that -adoption. The -HTTP download variant has not run in the cloud. Logical closure is implemented -for task release and never-provision-bound leaf cells. Later source `8dce857` -adds the narrow qualified provider-bound path described below. The historical port 4343 API used build `6fcd718` for the -Fly controller; that endpoint was subsequently observed unreachable. - -Source `67997585baa897bd7586fe21b9a755c89739a1a3` adds authenticated, read-only -Modal journal observation with private operator configuration and independent -content revisions. Its full combination passed **270/270**, exit 0, with unchanged -source during execution. A separate local API on port 4344 projected all three -actual journals and their 15 operations without changing their database/WAL bytes -or paid accounting. All three prefetch outcomes remain unknown. This view reports -persisted history rather than fresh provider status and does not establish model -inference or native Flow success. See [MODAL_OBSERVATION.md](MODAL_OBSERVATION.md) -for its separate contract and [QUALIFICATION.md](QUALIFICATION.md) for the exact -test and live-witness records. - -Source `8f5a94048e9c8be007cf3b5229607783b49cd47f` fixes the pinned vLLM startup -flag and adds complete artifact verification, private source/receipt binding and -read-only source preflight before paid resource admission. Its frozen combination -passed **274/274**, with matching source and historical paid-state bytes before -and after the final run. Earlier unstable/interrupted qualification attempts are -preserved separately. GPU boot, inference and native Flow remain unproven; -local artifact bytes were subsequently validated as described below. See the -[model definition](modal/README.md) and -[qualification record](QUALIFICATION.md). - -Actual local pinned-weight preparation passed after a reviewed resume. A separate -process independently validated all **13 files / 15.24 GB** in **61.60 seconds**, -with **30.8 MiB** peak memory. Both operations closed successfully and preserved -the protected source, history and owner state. This admits no new paid cloud work. See -[LOCAL_MODEL_PREPARATION.md](LOCAL_MODEL_PREPARATION.md) for its current evidence -and the separate remaining Modal/GPU/Flow requirements. - -The read-only API was restored on `127.0.0.1:4344` at build `8f5a940`; an actual -authenticated check again returned three journals and 15 operations without -changing their contents or paid accounting. The old port 4343 endpoint was not -restored. A brain-online adapter pinned to its old endpoint/build needs a reviewed -configuration update before using the restored service. - -Source `8dce857df549f29c69e566fa7d927196cb324c3c` adds provider-bound logical -leaf closure from recorded owned Fly teardown and a fresh configured-credential -inventory. Its complete frozen suite passed **288/288** and independent source -and outcome audits passed. The original child/parent worker cells are now retired -at controller events 90/91, preserving reviewed work and the unfinished root launch -task. Root logical capacity returned by $60 once; paid revision 17 still holds all -$100. Actual API checks project the new state under its existing loaded build -`8f5a940`. Physical quiescence and final billing remain unverified. See -[LIFECYCLE.md](LIFECYCLE.md) and [QUALIFICATION.md](QUALIFICATION.md). - -## Run locally - -Requirements: Node.js **24 or newer**, Git on `PATH`, and a local filesystem for -the controller database. There are no npm runtime dependencies to install. - -The full test suite additionally needs Python and the installed Modal SDK for -its definition checks. The genuine HTTP probes require explicit -`FACTORY_PYTHON`, `FACTORY_HUB_SITE` and `FACTORY_PRIVATE_MODULE` inputs: an -absolute base interpreter, owned site-packages containing Hub 0.36.0 and Requests, -and the trusted private-files module. Missing inputs fail rather than skip. -See [the Modal test instructions](modal/README.md) for the isolated probe scope. -Set these inputs before the complete test commands below. - -From this directory, with a suitable default Node: - -```powershell -node scripts/run-tests.mjs -node scripts/pilot.mjs .\evidence\local-pilot-01 + + + + + FACTORY, the swarm engine for your app. Your subscription, your own GPUs or any server flow into FACTORY and power your team of agents. + + +

Run a whole team of AI agents from a few lines of code.

+ +

+ FACTORY is a reusable swarm engine you drop into your own app.
+ Bring the AI subscription you already pay for, or host open models on your own GPUs. +

+ +

+ Latest release + MIT license + Node 22.17 or newer, or 24 or newer +

+ +

+ Try it  ·  + Bring your own AI  ·  + Go big  ·  + Full guide +

+ +
+ +## Try it in a minute + +```sh +npm install https://github.com/flujo-app/FACTORY/releases/download/v0.7.1/flujo-factory-0.7.1.tgz ``` -Use a fresh output directory for each deterministic pilot. The script preserves -its repository, controller database, candidate/review files, reconciliation -evidence and `report.json`; it deliberately does not reuse an existing fixture. +```js +import { Factory } from 'flujo-factory'; -The bundled runtime available on this machine is: +const factory = new Factory('team.sqlite'); -```powershell -$factoryNode = 'C:\Users\Moe\.cache\codex-runtimes\codex-primary-runtime\dependencies\node\bin\node.exe' -$env:FACTORY_PYTHON = 'C:\Users\Moe\AppData\Local\Programs\Python\Python313\python.exe' -$env:FACTORY_HUB_SITE = 'C:\Users\Moe\Documents\ChatGPT\FACTORY\.factory\model-local-20261003-r2\venv\Lib\site-packages' -$env:FACTORY_PRIVATE_MODULE = 'C:\Users\Moe\Documents\GitHub\flujo-cloud\lib\private-files.mjs' -& $factoryNode scripts/run-tests.mjs -& $factoryNode scripts/pilot.mjs .\evidence\local-pilot-01 +factory.createSwarm({ + mission: 'Build a landing page', + agents: [ + { id: 'builder', role: 'developer' }, + { id: 'reviewer', role: 'verifier' }, + ], +}); + +factory.startLiteWorker({ provider: 'claude', prompt: 'Work on the Factory board' }); ``` -`npm test` and `npm run pilot` use the default Node executable. Invoke the bundled -executable directly when the default installation is older than Node 24. +That's a team. Claude Code opens in your terminal on your normal login, sees the shared job board and gets to work. Change `'claude'` to `'codex'` to use Codex instead. -## What the deterministic pilot checks +> [!WARNING] +> Workers can read, change and run anything on the computer they're on, with no permission prompts. Start them in a folder or machine you're happy to hand over. -The pilot creates two candidate branches from one baseline. A separate evaluation -process accepts the correct implementation and rejects the competing fixture. A -single integration owner admits the accepted candidate's exact target, baseline -and commit. +
-The delivery subprocess then updates a real Git reference and exits before its -receipt is saved. A fresh controller observes the unresolved effect, refuses -takeover, inspects the actual Git reference and records reconciliation. It marks -the task delivered, grants a successor ownership epoch, rejects stale authority -and finishes with admission paused. +## Bring your own AI -The accompanying tests exercise concurrent processes sharing the SQLite database, -allocation conservation, duplicate identities, ownership fencing, candidate and -review binding, private result artifacts, receipt/finalization replay and atomic -Git compare-and-swap. The branch builders are deterministic fixtures; the pilot -does not measure model-generated development speed or improve production FLUJO. +Your agents, your choice of brain. Switching is one setting. -Read `report.json` for the evidence scope and result. `state.json` is an operational -snapshot; the SQLite database is the authoritative record. +| | 💳 Your subscription | 🖥️ Your own GPUs | 🔌 Any server | +|---|---|---|---| +| **Runs on** | Claude Code or Codex | Qwen or Nemotron, on your Modal account | Anything that speaks the OpenAI or Anthropic API | +| **You pay** | The plan you already have | From about $4.84 an hour while running, nothing when idle | Whatever that server costs | +| **Your code goes to** | That AI company | Nowhere. It stays in your account | That server | +| **Setup** | Sign in once | One function call | One setting | -## Controller CLI +
+🖥️ Host your own model +
-```powershell -node bin/factory.mjs -``` +Needs Python with `pip install modal`, and a signed-in Modal account. FACTORY sets up the GPU server, checks it works, and gives your agents the address and key. -Commands that need input read one JSON object from standard input. For example: +```js +import { ModalSelfHostedModel } from 'flujo-factory'; -```powershell -$factoryDatabase = Join-Path (Get-Location) '.factory\controller.sqlite' -'{"mission":"Improve FLUJO development speed","budgetCents":10000,"maxCells":5,"maxDepth":2}' | - node bin/factory.mjs init $factoryDatabase -node bin/factory.mjs status $factoryDatabase -node bin/factory.mjs pause $factoryDatabase -node bin/factory.mjs resume $factoryDatabase -``` +const model = new ModalSelfHostedModel({ directory: '/private/model' }); +await model.deploy({ profile: 'qwen' }); -Replace `node` with `& $factoryNode` when using the bundled runtime. - -| Command | JSON input | -| --- | --- | -| `init` | `mission`, `budgetCents`; legacy optional `maxCells`, `maxDepth`, or explicit `growthMode: "budget-only"` | -| `status`, `pause`, `resume` | No input | -| `growth-policy` | No input; read existing policy, epoch, status and policy digest | -| `budget-growth` | `transitionId`, `expectedFactoryEpoch`, `expectedPolicyDigest`; existing paused authority only | -| `reserve` | `cellId`, `budgetCents`, `purpose`; optional `parentId`, `role` | -| `enroll` | `cellId` | -| `task` | `taskId`, `projectId`, `branch`, `specification` | -| `claim` | `taskId`, `cellId`; optional `ttlMs` | -| `integration` | `projectId`; optional `cellId`, `ttlMs` | -| `message` | `sender`, `messageId`, `recipient`, `payload`; optional `taskId`, `attempt` | -| `inbox` | `cellId` | - -A task specification names `problem`, `acceptance` and `baseline`. Git delivery -also pins `deliveryTarget: {repository, ref}`. The reviewed candidate artifact -records `{repository, ref, baseline, candidateHead, branch}`; admission binds the -delivery request to those bytes. - -Lease responses contain private runner capability tokens. Keep them in -owner-private runner storage and exclude them from public reports. The CLI is a -trusted local operator interface. Worker authentication over HTTP, remote -enrollment and cross-host consensus are future work. - -## State, pause and recovery - -`control.status: active` permits admission; it does not mean workers have started. -`paused` revokes new admission and advances the control epoch. `resume` advances -it again, so old leases remain stale. - -`effectsDrained` means the ledger has no accepted, running or unknown effects. -`workerQuiescence: unverified` means the controller has not established that every -worker/process has stopped. A paused controller can still have an admitted effect -finishing or an unresolved external outcome. This pilot does not stop unrelated -Codex chats, automations or processes. - -An effect's stable key and request digest identify its intent. Matching receipt -replay and delivery finalization preserve the original result without dispatching -again or recording a second completion. A different request or ownership attempt -cannot reuse that key. - -After interruption, inspect the existing task, effect and destination before -retrying. A timeout does not prove an operation failed. Unresolved effects block -conflicting takeover. An accepted intent that never started can be cancelled; -negative reconciliation of a started or unknown effect is deliberately -unsupported without executor proof. The local Git pilot demonstrates positive -reconciliation of an observed exact commit. `executeGitDelivery` in -`src/git-effect.mjs` adds a narrow exception for a completed, genuine local Git -compare-and-swap refusal: it settles as `not_applied` using a bound, single-use -in-process proof. A timeout, killed executor, forged error or missing receipt -still remains unknown. Refusal leaves the reviewed task undelivered; rebasing -requires a new candidate and review. - -Preserve the controller database and recovery artifacts. For cloud operations, -also preserve `ManagedCloud` attempt metadata, journals and credentials until -owned retirement is confirmed. A new worker name is a new deployment, not a -recovery of the previous uncertain attempt. - -## Read-only cloud preflight - -The preflight script verifies an explicitly selected native source, reads -workspace/configuration metadata and checks compatible official-image selection. -It creates no deployment and runs no Flow. - -```powershell -node scripts/cloud-preflight.mjs ` - --module-path 'C:\Users\Moe\Documents\GitHub\flujo-cloud\lib\managed.mjs' ` - --source 'http://127.0.0.1:4200' ` - --workspace 'factory-pilot' +factory.startLiteWorker({ + provider: 'claude', + modelProvider: model.endpoint(), + providerKey: await model.key(), +}); ``` -Use the actual registered source origin. Exit code `0` means compatible image -selection was confirmed; `2` means selection was unconfirmed or the workspace was -absent; `1` means the preflight itself could not be confirmed. This is preparation -evidence, not a running-worker acceptance result. - -## Isolated live pilot operation - -The spending intent is **at most US$100 across the paid cloud work**, including -the Modal/open-weight model path. `src/spending.mjs` conserves one durable USD -allowance across providers, using integer cents and serialized admission. The -first experiment reserved $10 for Fly and $30 for Modal. Two further, distinct -Modal experiments each hold $30; all $100 is reserved and $0 remains unallocated. Current -results and billing status are recorded in [QUALIFICATION.md](QUALIFICATION.md). -All four reservations are now retired pending final billing, with the full holds -unchanged. The latest paid revision is 19; its 30 recorded cents are conservatively -rounded partial observations, not exact total spend. No fresh paid experiment is -admitted by the source update. -Each paid dispatch rechecks its reservation; known experiment or global exhaustion -blocks new paid work. Owned cleanup remains possible. Retirement keeps funds held -until final billing evidence arrives; it cannot release uncertain charges. The -ledger covers registered factory spending, not unrelated provider-account costs. - -The local `budgetCents` and child -allocations conserve delegated budget; they do not meter actual compute, -inference, storage or provider charges and are not a provider-side billing stop. -An experiment needs explicit resource/time limits and observed cleanup as well as -budget records. Overall factory work has no time limit; the limits below apply to -this first Fly experiment. - -The initial live slice is bounded to **two temporary cloud workers**, delegation -depth **two**, Flow-call timeout **180 seconds**, and a **15-minute work deadline**. -It uses a dedicated `factory-pilot` workspace with a minimal Flow and no attached -MCP tools. The first worker produces a bounded function candidate and a -schema-validated child request. The local coordinator admits and provisions that -child from its parent's allocation. The child returns a JSON review, and the local -verifier checks the candidate's exact pure-function grammar and fixed acceptance -table. Generated code is preserved as an artifact and is never executed locally. - -The work deadline bounds new admission and individual HTTP/Fly commands. It does -not guarantee a global cancellation or shutdown time. Owned cleanup has a separate -five-minute command deadline. - -The live runner prepares read-only unless `--execute` is supplied: - -```powershell -$cloudPilotDirectory = Join-Path (Get-Location) '.factory\cloud-pilot-01' -node scripts/cloud-pilot.mjs ` - --run-id 'cloud-pilot-01' ` - --output $cloudPilotDirectory ` - --module-path 'C:\Users\Moe\Documents\GitHub\flujo-cloud\lib\managed.mjs' ` - --source 'http://127.0.0.1:4200' +When you're done, `await model.retire()` deletes it all. [More on self-hosting →](selfhost/README.md) + +
+ +
+🔌 Use any server +
+ +```js +factory.startLiteWorker({ + provider: 'claude', + modelProvider: { + id: 'my-server', + envKey: 'MY_MODEL_KEY', + baseUrls: ['https://models.example.com/v1'], + apis: ['anthropic'], + model: 'my-model', + }, + providerKey: process.env.MY_MODEL_KEY, +}); ``` -Use the registered native source origin. Add `--execute` and -`--spending-ledger` with the absolute path of the shared `.factory\spending.sqlite` -to this same invocation -to run the isolated pilot. The runner refuses to adopt an existing fixture -workspace. An existing manifest returns `observe-existing` without reprovisioning -or replaying model calls; inspect its original attempts before further recovery. -Exit code `2` means the live proof failed or an existing run needs reconciliation. -An explicit `--resume-fixture` is limited to the original pre-cloud fixture -failure: original source/image/manifest, empty owned workspace creation proof, -fixed model/Flow inventory, paused controller and zero historical effects are -required. Recovery preserves its old report and app identities. It is not a -general cloud retry. -The runner verifies that the source's default agent uses the approved -`gpt-6-astra / codex / codex-cli` model tuple; it does not change that source -binding. The dedicated source workspace remains available for inspection after -cloud retirement. - -This qualifies gateway-mediated delegation if it succeeds. Native autonomous -child provisioning, cross-host ownership, mutual monitoring, source branch -development and fleet learning each still need their own proofs. - -Owned retirement belongs in the runner's `finally` path and uses a narrow trusted -local cleanup authority. That authority can retire an app while admission is -paused only when the app is bound to this controller's original provisioning -intent. It cannot grant a general work lease or resume dispatch. Retirement -identity validation requires the matching app and a terminal destroyed result; -uncertain cleanup remains unresolved and cannot be blindly retried under another -key. Existing unresolved work records remain intact. - -`ManagedCloud.down` verifies the deployment's journal and cloud ownership before -deleting its dedicated application. A failed or uncertain retirement must remain -visible with its original identities and recovery records. Deadline expiry alone -is not evidence that a resource was retired; recovery must inspect and reconcile -it. A separate same-host watcher can record heartbeat, ledger and live provider -observations; it cannot grant ownership, retire resources or recover from loss of -the host itself. - -For an observation after the manifest and controller ledger exist: - -```powershell -node scripts/watch-pilot.mjs ` - --manifest (Join-Path $cloudPilotDirectory 'manifest.json') ` - --module-path 'C:\Users\Moe\Documents\GitHub\flujo-cloud\lib\managed.mjs' ` - --fly-path 'C:\Users\Moe\.fly\bin\flyctl.exe' ` - --once +
+ +
+ +## Go big + +The same idea, on as many cloud machines as you want. Needs a [Fly.io](https://fly.io) account and [flujo-cloud](https://github.com/flujo-app/flujo-cloud). + +```js +import { FactoryCloudLiteFleet, ClaudeSubscriptionBroker } from 'flujo-factory'; + +const fleet = new FactoryCloudLiteFleet({ + directory: '/private/fleet', + flujoCloudPath: '/path/to/flujo-cloud', + auth: new ClaudeSubscriptionBroker({ tokenFile: '/private/claude-token' }), +}); + +await fleet.deploy({ + runId: 'launch', + app: 'my-swarm', + goal: 'Fix every open bug', + workerProgram: 'claude', + machines: 10, + agentsPerMachine: 10, +}, { image, bundlePath }); ``` -Use the actual absolute Fly executable path. Without `--once`, the watcher runs a -bounded observation loop. It records provider evidence in -`watch-observations.jsonl` and can send structured observations to the local root -inbox. A witness of app absence is stronger than cached inventory; it still does -not establish metered spend or full worker quiescence. If the coordinator dies, -the witness can report that condition but cannot perform teardown. - -### Source and image boundaries - -The existing shared FLUJO checkout is dirty; its checkout and running build were -preserved. The one-file API documentation task used a fresh isolated worktree at -upstream `d68492712315d30c856c8d2ba95b0a26a859bd18`. Independent review accepted -candidate `ea66f1130e01d3208173cd850d40f85f319b3582`, and the reviewed local target -`refs/heads/codex/factory-reviewed-api-token-limit-docs` received that exact commit -through Git compare-and-swap. This corrected HTTP versus authored Flow token-limit -documentation; it created no PR, push, upstream merge or runtime change. Runtime -FLUJO improvements and upstream publication still require their own acceptance. -The task's `docs-builder` and `docs-reviewer` cells were then logically retired -using the qualified controller subset. Independent audit confirmed the exact -closure events, preserved delivered work and unchanged billing records. -Provider/process quiescence remains unverified. - -The cloud bridge snapshots durable workspace state from a running native source -and selects a compatible immutable worker image. Application-version or channel -fallback establishes the declared compatibility contract; it does not establish -equality with an unreported or dirty local Git checkout. Preserve the selected -source, snapshot and image identities in live evidence. - -Flow selection controls startup/call scope and does not redact unrelated -workspace data or credentials. Use the dedicated workspace to constrain the -transferred contents. Copied model authentication and shared provider accounts -also retain common failure dependencies; two cloud workers do not by themselves -prove independent authentication or inference availability. - -## Current limits - -- One local SQLite authority; no distributed failover or consensus qualification. -- Trusted local processes and filesystem; worker isolation and gateway-only - external credentials need separate enforcement. -- One real isolated documentation delivery and deterministic recovery fixtures; - no unattended roadmap execution or measured factory self-improvement. -- Logical watcher/cell/message records; no independently hosted watchdog is - established by the local pilot. -- Provisioning adapter over existing `ManagedCloud`; the bounded Fly deployment, - model calls and owned cleanup passed. General remote-result reconciliation, - automatic health recovery, runtime-source improvement and upstream publication - remain unqualified. + + + + + + +

100

agents on 10 cloud machines
in one real run

190

agents sharing one GPU
in one real coding run

~$20

of GPU time for that run
2 hours 18 minutes
+ +
+ +## What you get + + + + + + + + + + + + + + +
🗂️ A shared job board
Agents claim work, so two never pick up the same job.
✅ Independent review
One agent builds, another checks. Work only counts once it passes.
♻️ Survives crashes
Restart any time. A job that was already sent is never sent twice.
💰 Budgets
Give each agent a share. It can't hand out more than it has.
🤖 Your choice of worker
Claude Code, Codex or FLUJO, on your PC or in the cloud.
🧩 Use it your way
From your code, from the command line, or as an MCP tool for other agents.
+ +
+ +## Good to know + +- **Budgets are bookkeeping.** They limit what FACTORY hands out. They don't stop your provider from charging you, so set limits there too. +- **Check your AI plan's terms** before running lots of agents on one subscription. +- **Not on npm yet.** Install from [GitHub Releases](https://github.com/flujo-app/FACTORY/releases), as shown above. +- **In the cloud you can lock agents down** with `sandbox: 'workspace-write'`. [See the guide.](PUBLIC_SDK.md#claude-code-as-the-worker-program) + +
+ +## Learn more + +[Full SDK guide](PUBLIC_SDK.md)  ·  [Self-hosted models](selfhost/README.md)  ·  [Reviewed workflows](WORKFLOWS.md)  ·  [Early pilot notes](https://github.com/flujo-app/FACTORY/blob/main/PILOT_NOTES.md) + +Part of the FLUJO family. MIT licensed, including commercial use. diff --git a/assets/banner-dark-still.webp b/assets/banner-dark-still.webp new file mode 100644 index 0000000..233d89b Binary files /dev/null and b/assets/banner-dark-still.webp differ diff --git a/assets/banner-dark.webp b/assets/banner-dark.webp new file mode 100644 index 0000000..41b1b6d Binary files /dev/null and b/assets/banner-dark.webp differ diff --git a/assets/banner-light-still.webp b/assets/banner-light-still.webp new file mode 100644 index 0000000..0fe84b4 Binary files /dev/null and b/assets/banner-light-still.webp differ diff --git a/assets/banner-light.webp b/assets/banner-light.webp new file mode 100644 index 0000000..e5cbbc8 Binary files /dev/null and b/assets/banner-light.webp differ diff --git a/deploy/factory-service.md b/deploy/factory-service.md index 42fa201..75d4d5c 100644 --- a/deploy/factory-service.md +++ b/deploy/factory-service.md @@ -20,7 +20,7 @@ The entrypoint sets `umask 077` and uses `exec`, leaving Node as PID1 to receive SIGTERM. Files in `/app` remain root-owned; the process runs as uid/gid1000. `deploy/private-files.mjs` is a verbatim verified copy of -`C:/Users/Moe/Documents/GitHub/flujo-cloud/lib/private-files.mjs`, captured for +`flujo-cloud/lib/private-files.mjs`, captured for this packaging increment. Its SHA256 is `7ae5ba87ec1cd387ee1b914105894d29254e07c0a3644c86f65810f461dcd54d`. It imports only Node builtins, implements owner-private files on POSIX and