Chio/Docs
LOGIN · JOIN

Build a software factory

Turn an issue into a patch, test and review one exact candidate, and publish only the candidate the release owner approves.

Guide chio@5f63e6e

On this page

A software factory closes the loop from an observable defect to a tested, reviewed change. This application supplies a broken Python project and immutable tests; a repair worker edits allowed source files, signed graph continuations authorize testing and review, and the release owner decides whether the exact candidate is published to a local release directory.

Run the factory

A failing project becomes one tested, reviewed candidate

Build it. Run it. Inspect it.

From issue to a tested candidate

A repair worker edits a confined project. Separate graph continuations authorize implementation, testing, and candidate review.

Download project
Your inputs

Hosted records are retained for seven days. Use the downloaded project for local work and your own model credentials.

Loading the verified example result…

Inspect the failing baseline, the candidate diff, the focused test output, and the review. The deterministic adapter supplies a regression repair for fast exploration; model mode generates a new patch through governed repository tools. After a live run, approve or reject the candidate shown. Approval publishes only inside this run’s isolated project and retains a separate publication receipt.

Each responsibility spends one continuation and publication needs its own approval

The graph bounds what each worker may do and how often. The candidate’s digest ties the test and review results to the change they examined, and the release owner’s approval binds publication to that digest.

Software factoryChoose a lens.
write_filetestreviewcandidateproposalsignspublicationcontinuationapprovesno approvalκTask graphone-use continuationsa₁Implementeredits sourcea₂Test workertests the candidatea₃Reviewerreviews the candidateKKernelcCandidateone digestτRelease ownerdRelease toolρReceiptsapprovesno approvalκTask grapha₁Writea₂Testa₃ReviewKKernelcCandidateτApproverdReleaseρReceipts

Each responsibility spends one continuation

The host mints a task graph for implementation, testing, and review with bounded allocations and one-use continuations. Publication needs a separate approval bound to the proposed parameters; a publish without it is refused. Continuations.

The software factory application: the task graph, three workers, one candidate, the release owner's approval, and the release tool. The planner call and the bubblewrap test sandbox are left out.

Repository tools touch only the configured files

The repair worker can list, read, and write the configured project files, and the immutable test file is read-only. Tool handlers validate each path before they touch the workspace. In model mode, the conversation loop proposes these same tool calls and receives the admitted results.

software-factory/src/repository.rsL115–131rust
    fn write(&self, path: &str, content: &str) -> Result<Value> {
        simple_path(path)?;
        anyhow::ensure!(
            self.editable.iter().any(|p| p == path),
            "File is outside the worker's editable set"
        );
        anyhow::ensure!(content.len() <= 32_000, "File exceeds 32000 bytes");
        let destination = self.directory.join(path);
        anyhow::ensure!(
            !destination.symlink_metadata()?.file_type().is_symlink(),
            "Refusing to replace a symlink"
        );
        chio_agent_os_shared::runtime::files::replace(&destination, content.as_bytes())?;
        self.writes
            .fetch_add(1, std::sync::atomic::Ordering::SeqCst);
        Ok(json!({"path":path,"candidate_sha256":self.digest_unlocked()?}))
    }

Open this excerpt in the complete source

In the verified run, event 25 refuses a write to a path outside the editable files, with receipt 17292436…26ce6f.

The host issues authority for the actual task graph

The host mints a graph for implementation, testing, and review from the delegated capabilities. It records the graph, route references, bounded allocations, and one-use continuations, and runtime admission consumes a continuation before each worker call. Application order and acceptance criteria stay visible in this file.

software-factory/src/lib.rsL234–267rust
        let root = host.root("factory-workers", &["implement", "test", "review"], 3)?;
        let implement = host.delegate(&run, &root, "implement", &["implement"], 1, 3000)?;
        let test = host.delegate(&run, &root, "test", &["test"], 1, 3000)?;
        let review = host.delegate(&run, &root, "review", &["review"], 1, 3000)?;
        let tasks = [
            ("implement", &implement),
            ("test", &test),
            ("review", &review),
        ];
        let bundle = host.mint_graph(SwarmFanoutRequest {
            graph_id: run.id()?,
            root_transaction_ref: planned.receipt_id.clone(),
            parent_receipt_id: planned.receipt_id,
            session_anchor: run.id()?,
            parent: root.token,
            tasks: tasks
                .iter()
                .map(|(task, cap)| SwarmFanoutTask {
                    task_id: task.to_string(),
                    capability: (*cap).clone(),
                    protocol_target: "local://factory-workers".into(),
                    reserved_units: 1,
                })
                .collect(),
            policy_digest: chio_core::sha256_hex(b"factory-signed-task-graph-v1"),
            now_unix_ms: chio_agent_os_shared::events::now_ms(),
            lifetime_ms: 110_000,
        })?;
        run.emit("graph.issued","planner","Issued authority for three bounded responsibilities",json!({
    "graph":bundle.task_graph,
    "continuations":bundle.continuation_tokens,
    "trusted_issuer":host.signer.to_hex(),
    "scheduling":"The application orders implement, test, and review; the graph assigns authority and joins their results"
}))?;

Open this excerpt in the complete source

Event 07 issues the three continuations. Event 17 refuses a reused implementation continuation, with receipt 99ca5cfa…fce8a4.

Tests and review bind to one candidate

Testing and review each compare the requested candidate with the current repository digest, and review also checks that the retained test result names that candidate. Passing checks and a structured review permit a completion join; publication is a separate decision. The review is a deterministic release check over the diff.

software-factory/src/lib.rsL100–128rust
            "test" => {
                anyhow::ensure!(
                    input["candidate_sha256"] == self.repository.digest()?,
                    "Tests requested for a stale candidate"
                );
                let result = self.repository.test(false).await?;
                *self
                    .tests
                    .lock()
                    .map_err(|_| anyhow::anyhow!("Test result lock failed"))? =
                    Some(result.clone());
                Ok(result)
            }
            "review" => {
                let candidate = self.repository.digest()?;
                anyhow::ensure!(
                    input["candidate_sha256"] == candidate,
                    "Review requested for a stale candidate"
                );
                let tests = self
                    .tests
                    .lock()
                    .map_err(|_| anyhow::anyhow!("Test result lock failed"))?
                    .clone()
                    .context("Run tests before requesting review")?;
                anyhow::ensure!(
                    tests["candidate_sha256"] == candidate,
                    "Tests belong to another candidate"
                );

Open this excerpt in the complete source

Event 19 refuses tests for a stale candidate. Event 27 joins the three receipts the workers actually returned.

Publication happens once, for the approved candidate

The release tool checks eligibility, the candidate digest, and the exact file set before it stages the release. The separate approval binds the proposed parameters, the publication keeps its receipt, and repeating the same decision recovers that terminal result. Tests run with network access off and read-only project and system files.

software-factory/src/publication.rsL43–82rust
    fn publish(&self, args: Value) -> Result<Value> {
        anyhow::ensure!(
            args == self.proposal["arguments"],
            "Publication parameters differ from the reviewed proposal"
        );
        let files = read_files(
            &self.directory.join("project/candidate"),
            &self.proposal["files"],
        )?;
        anyhow::ensure!(
            digest(&files)? == args["candidate_sha256"],
            "Candidate changed after approval; run the tests and review the new candidate"
        );
        let destination = self.directory.join("release");
        anyhow::ensure!(
            !destination.exists(),
            "Release already exists; reconcile it instead of publishing again"
        );
        let staged = chio_agent_os_shared::runtime::files::StagedDirectory::new(&self.directory)?;
        for (name, contents) in &files {
            chio_agent_os_shared::runtime::files::create(
                &staged.path().join(name),
                contents.as_bytes(),
            )?;
        }
        write_json(
            &staged.path().join("release.json"),
            &json!({
                "candidate_sha256":args["candidate_sha256"],
                "test_receipt":args["test_receipt"],
                "review_receipt":args["review_receipt"],
                "files":files.keys().collect::<Vec<_>>()
            }),
        )?;
        staged.publish(&destination)?;
        Ok(
            json!({"published":true,"candidate_sha256":args["candidate_sha256"],"files":files,"release_directory":"release"}),
        )
    }
}

Open this excerpt in the complete source

Event 30 refuses a publish that carries no approval token, with receipt d4d4b229…c6955c.

Replay, revocation, stale tests, and unapproved publication change nothing

The sample input tries each refusal after the candidate exists. The retained run shows the candidate unchanged:

Terminalbash
./run --run input.json
Retained events, captures/verified.json
17  call.denied               implement
    chio swarm-bound runtime continuation replay denied
    receipt 99ca5cfa…fce8a4
19  call.denied               stale-test-worker
    tool server error: Tests requested for a stale candidate
    receipt d5ac4240…c3e155
21  call.denied               revoked-repair-worker
    capability has been revoked: cap-01a08c22-703d-7a71-8505-88b8eb09bf43
    receipt 13c64fff…a8d82a
23  call.denied               review-worker
    requested tool write_file on server repository is not in capability scope
    receipt c5487c4e…6bbbc9
26  factory.refusals          operator
    Replay, revocation, stale tests, and unauthorized edits left the candidate
    unchanged
30  call.denied               unapproved-publisher
    governed transaction denied: approval token required for governed transaction
    intent 371826d6-26b9-44d8-ba49-1aaa027e8091
    receipt d4d4b229…c6955c
  • Write a path outside the editable project: no file changes.
  • Reuse an implementation continuation or revoke the edit grant: the candidate stays unchanged.
  • Present stale test evidence or a changed approval digest: no release is published.
  • Reject publication: the candidate and its evidence stay, unshipped.

The downloadable tests assert each effect or its absence: run cargo test --locked -p chio-software-factory from the extracted project.

Run the factory on your machine

Keep the run directory to review the tested candidate and reconcile its publication decision.

From the extracted projectbash
cd chio-software-factory
./run

The archive holds the application, the shared host code, tests, sample input, pinned dependencies, and a README. The launcher builds and runs the Rust source included in this archive. Install Rust 1.94.1 and the README’s native prerequisites; filesystem isolation and operator workloads require the listed Linux host profile. Cargo resolves immutable public dependencies, so a sibling checkout is unnecessary.

For model workers, set OPENROUTER_API_KEY on the local host and select model mode; credentials stay on that host and never enter the docs form. The qualified model is openai/gpt-4.1-mini. Analysis, retrieval, and deterministic worker modes run without a model key. Ctrl-C stops the local web process and its active child work and keeps the run directory.

Download identity and source revision

Download complete project · View public source

Project archive SHA-256text
753ca6667a9a1585da87886abd16a1f169ddbb563f483ec49122be08a8e7860a

Point the factory at your own project

Set CHIO_FACTORY_WORKSPACE to a small Python project in the included chio-factory.json layout. Name the editable files and one immutable focused test, then use model mode to repair the failing case. A GitHub publication adapter can replace the local release directory, with its approval bound to the same tested candidate.

Next: build a cognition marketplace