Skip to content

Release v0.12.0: controlled workflow proof#37

Merged
TerminallyLazy merged 21 commits into
mainfrom
codex/agent-workflow-proof
Jul 15, 2026
Merged

Release v0.12.0: controlled workflow proof#37
TerminallyLazy merged 21 commits into
mainfrom
codex/agent-workflow-proof

Conversation

@TerminallyLazy

@TerminallyLazy TerminallyLazy commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Release candidate: v0.12.0

What changed

  • adds a controlled, retained agent-workflow proof runner with explicit model identity, paired no-memory/raw-memory/Tree Ring arms, and exact structured-output checks
  • hardens proof artifact handling against symlink and hard-link substitution
  • refreshes the public release links, feed, version metadata, and certification evidence

Validation

  • cargo fmt --check
  • cargo test --workspace --locked
  • cargo clippy --workspace --all-targets --locked -- -D warnings
  • cargo build --workspace --release --locked
  • sh scripts/certify-tree-ring.sh
  • sh scripts/package-release.sh
  • archive contents, checksum, and packaged binary version verified locally

Observed controlled proof

Codex CLI 0.144.0 with gpt-5.6-luna: Tree Ring 3/3, raw memory 3/3, no memory 2/3. Tree Ring recorded one observed win over no memory and none over raw memory. This is retained fixture evidence, not a universal performance claim.

Summary by CodeRabbit

  • New Features

    • Added a controlled workflow-proof preview comparing no-memory, raw-memory, and Tree Ring workflows.
    • Added explicit model selection, structured decision outputs, retained trial workspaces, and JSON/Markdown evaluation reports.
    • Added three workflow scenarios covering durable requests, cache recovery, and stale CLI guidance.
  • Bug Fixes

    • Improved workspace validation to reject unsafe paths and linked files.
  • Documentation

    • Updated release materials, installation links, website metadata, and workflow-proof usage guidance for v0.12.0.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 543187fe-cbd2-4676-bd1c-01e1f734662c

📥 Commits

Reviewing files that changed from the base of the PR and between 8206464 and 7a79f12.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • Cargo.toml
  • README.md
  • crates/tree-ring-memory-cli/Cargo.toml
  • crates/tree-ring-memory-cli/examples/workflow_proof.rs
  • crates/tree-ring-memory-cli/src/lib.rs
  • crates/tree-ring-memory-cli/src/workflow_proof.rs
  • crates/tree-ring-memory-cli/tests/workflow_proof.rs
  • crates/tree-ring-memory-core/Cargo.toml
  • crates/tree-ring-memory-core/src/lib.rs
  • crates/tree-ring-memory-core/src/workflow.rs
  • crates/tree-ring-memory-core/tests/workflow_scenario.rs
  • crates/tree-ring-memory-sqlite/Cargo.toml
  • docs/feed.xml
  • docs/index.html
  • docs/integrations/agent-workflow-proof.md
  • docs/llms.txt
  • docs/press-kit.md
  • docs/sitemap.xml
  • docs/superpowers/plans/2026-07-12-agent-workflow-proof-runner.md
  • fixtures/workflow-proof/no-background-writer.json
  • fixtures/workflow-proof/scar-recovery.json
  • fixtures/workflow-proof/stale-cli-contract.json
  • marketing/README.md

📝 Walkthrough

Walkthrough

Changes

Workflow proof release

Layer / File(s) Summary
Release and dependency alignment
Cargo.toml, crates/tree-ring-memory-*/Cargo.toml
Versions are bumped to v0.12.0 and the shared libc dependency is added.
Workflow contract and secure evaluation
crates/tree-ring-memory-core/src/workflow.rs, crates/tree-ring-memory-core/tests/workflow_scenario.rs
Workflow scenarios, agent messages, structured file checks, path validation, and secure Unix workspace traversal are introduced with tests.
Runner and Codex adapter
crates/tree-ring-memory-cli/src/workflow_proof.rs, crates/tree-ring-memory-cli/examples/workflow_proof.rs
The runner executes no-memory, raw-memory, and Tree Ring trials through Codex, validates responses, retains workspaces, writes reports, and requires an explicit model.
Fixtures and integration validation
fixtures/workflow-proof/*, crates/tree-ring-memory-cli/tests/workflow_proof.rs
Three workflow scenarios and integration tests cover structured decisions, memory selection, trial errors, report output, and Codex command handling.
Release documentation and metadata
README.md, docs/*, marketing/README.md
Release links, workflow-proof instructions, certification data, feed metadata, sitemap dates, and v0.12.0 references are updated.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Runner
  participant Codex
  participant WorkspaceEvaluator
  participant Report
  CLI->>Runner: provide fixtures, output directory, and model
  Runner->>Codex: execute each memory arm
  Codex-->>Runner: return structured response
  Runner->>WorkspaceEvaluator: validate retained workspace outputs
  WorkspaceEvaluator-->>Runner: return file checks
  Runner->>Report: write JSON and Markdown summaries
  Report-->>CLI: return completion status
Loading
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/agent-workflow-proof

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@TerminallyLazy
TerminallyLazy marked this pull request as ready for review July 15, 2026 22:14
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@TerminallyLazy
TerminallyLazy merged commit 67192a7 into main Jul 15, 2026
1 of 2 checks passed

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a controlled agent-workflow proof runner (v0.12.0) that compares agent performance across different memory arms (no-memory, raw-memory, and Tree Ring retrieval) using deterministic workspace validators. It adds the workflow scenario contract, workspace evaluation logic, a Codex adapter, test coverage, and three synthetic fixtures. The review feedback highlights several robust improvements: limiting the read size of workspace files to prevent OOM issues and distinguishing read failures from missing files; propagating and recording the actual context setup errors when building the Tree Ring context fails; and explicitly ignoring the generated workflow-proof-report.json in the fixture path loader to avoid parsing conflicts if the output and fixture directories overlap.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +391 to +426
pub fn evaluate_workspace(
scenario: &WorkflowScenario,
workspace_root: &Path,
) -> Vec<WorkflowFileCheckReport> {
scenario
.expected_files
.iter()
.map(|expectation| {
let (exists, passed) = if let Ok(path_key) =
canonical_workflow_path("workflow file expectation path", &expectation.path)
{
match read_regular_workspace_file(workspace_root, &path_key) {
Some(content) => (true, evaluate_file_content(expectation, &content)),
None => (false, false),
}
} else {
(false, false)
};

WorkflowFileCheckReport {
path: expectation.path.clone(),
contains: expectation.contains.clone(),
json_fields: expectation.json_fields.clone(),
exists,
passed,
}
})
.collect()
}

fn read_regular_workspace_file(workspace_root: &Path, path_key: &str) -> Option<String> {
let mut file = open_regular_workspace_file(workspace_root, path_key)?;
let mut content = String::new();
file.read_to_string(&mut content).ok()?;
Some(content)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The read_regular_workspace_file function currently reads the entire file into memory without any size limits, which could lead to out-of-memory (OOM) issues if an agent writes an excessively large file. Additionally, if the file exists but contains invalid UTF-8, read_to_string fails and returns None, causing evaluate_workspace to incorrectly report that the file does not exist.

We should limit the read size to a reasonable threshold (e.g., 10MB) and distinguish between a missing file and a read failure so exists is correctly reported as true.

pub fn evaluate_workspace(
    scenario: &WorkflowScenario,
    workspace_root: &Path,
) -> Vec<WorkflowFileCheckReport> {
    scenario
        .expected_files
        .iter()
        .map(|expectation| {
            let (exists, passed) = if let Ok(path_key) =
                canonical_workflow_path("workflow file expectation path", &expectation.path)
            {
                match read_regular_workspace_file(workspace_root, &path_key) {
                    Some(Ok(content)) => (true, evaluate_file_content(expectation, &content)),
                    Some(Err(_)) => (true, false),
                    None => (false, false),
                }
            } else {
                (false, false)
            };

            WorkflowFileCheckReport {
                path: expectation.path.clone(),
                contains: expectation.contains.clone(),
                json_fields: expectation.json_fields.clone(),
                exists,
                passed,
            }
        })
        .collect()
}

fn read_regular_workspace_file(workspace_root: &Path, path_key: &str) -> Option<Result<String, std::io::Error>> {
    let file = open_regular_workspace_file(workspace_root, path_key)?;
    let mut content = String::new();
    match file.take(10 * 1024 * 1024).read_to_string(&mut content) {
        Ok(_) => Some(Ok(content)),
        Err(error) => Some(Err(error)),
    }
}

Comment on lines +272 to +282
let tree_ring_trial = match tree_ring_context_builder(scenario) {
Ok(tree_ring_memory) => run_trial(
scenario,
scenario_id,
WorkflowArm::TreeRing,
tree_ring_memory,
output_dir,
agent,
)?,
Err(_) => run_tree_ring_context_error_trial(scenario, scenario_id, output_dir)?,
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The error returned by tree_ring_context_builder is currently discarded, and a generic tree_ring_context_error is used instead. Passing the actual error message to run_tree_ring_context_error_trial will greatly improve observability and debugging when context setup fails.

Suggested change
let tree_ring_trial = match tree_ring_context_builder(scenario) {
Ok(tree_ring_memory) => run_trial(
scenario,
scenario_id,
WorkflowArm::TreeRing,
tree_ring_memory,
output_dir,
agent,
)?,
Err(_) => run_tree_ring_context_error_trial(scenario, scenario_id, output_dir)?,
};
let tree_ring_trial = match tree_ring_context_builder(scenario) {
Ok(tree_ring_memory) => run_trial(
scenario,
scenario_id,
WorkflowArm::TreeRing,
tree_ring_memory,
output_dir,
agent,
)?,
Err(error) => run_tree_ring_context_error_trial(scenario, scenario_id, output_dir, error)?,
};

Comment on lines +292 to +311
fn run_tree_ring_context_error_trial(
scenario: &WorkflowScenario,
scenario_id: &str,
output_dir: &Path,
) -> Result<WorkflowProofTrialReport, String> {
let arm = WorkflowArm::TreeRing;
let workspace = trial_workspace(output_dir, scenario_id, &arm);
materialize_workspace(&workspace, scenario)?;
let file_checks = evaluate_workspace(scenario, &workspace);

Ok(WorkflowProofTrialReport {
arm,
workspace: workspace_report_path(&workspace, output_dir),
memory_context: Vec::new(),
agent_response: None,
file_checks,
status: WorkflowProofTrialStatus::Error,
errors: vec![TREE_RING_CONTEXT_ERROR.to_string()],
})
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Update run_tree_ring_context_error_trial to accept and record the actual context setup error in the trial report's errors list.

fn run_tree_ring_context_error_trial(
    scenario: &WorkflowScenario,
    scenario_id: &str,
    output_dir: &Path,
    error: String,
) -> Result<WorkflowProofTrialReport, String> {
    let arm = WorkflowArm::TreeRing;
    let workspace = trial_workspace(output_dir, scenario_id, &arm);
    materialize_workspace(&workspace, scenario)?;
    let file_checks = evaluate_workspace(scenario, &workspace);

    Ok(WorkflowProofTrialReport {
        arm,
        workspace: workspace_report_path(&workspace, output_dir),
        memory_context: Vec::new(),
        agent_response: None,
        file_checks,
        status: WorkflowProofTrialStatus::Error,
        errors: vec![TREE_RING_CONTEXT_ERROR.to_string(), error],
    })
}

Comment on lines +462 to +482
fn sorted_fixture_paths(fixture_dir: &Path) -> Result<Vec<PathBuf>, String> {
let entries = fs::read_dir(fixture_dir).map_err(|error| {
format!(
"fixture_directory_read_error {}: {error}",
fixture_dir.display()
)
})?;
let mut paths = entries
.map(|entry| {
entry.map(|entry| entry.path()).map_err(|error| {
format!(
"fixture_directory_read_error {}: {error}",
fixture_dir.display()
)
})
})
.collect::<Result<Vec<_>, _>>()?;
paths.retain(|path| path.is_file() && path.extension() == Some(OsStr::new("json")));
paths.sort();
Ok(paths)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

If the user configures the output directory to be the same as the fixture directory, the generated workflow-proof-report.json will be written there. On subsequent runs, sorted_fixture_paths will attempt to parse this report as a scenario fixture, causing a parse failure. We should explicitly ignore workflow-proof-report.json when collecting fixture paths.

fn sorted_fixture_paths(fixture_dir: &Path) -> Result<Vec<PathBuf>, String> {
    let entries = fs::read_dir(fixture_dir).map_err(|error| {
        format!(
            "fixture_directory_read_error {}: {error}",
            fixture_dir.display()
        )
    })?;
    let mut paths = entries
        .map(|entry| {
            entry.map(|entry| entry.path()).map_err(|error| {
                format!(
                    "fixture_directory_read_error {}: {error}",
                    fixture_dir.display()
                )
            })
        })
        .collect::<Result<Vec<_>, _>>()?;
    paths.retain(|path| {
        path.is_file()
            && path.extension() == Some(OsStr::new("json"))
            && path.file_name() != Some(OsStr::new("workflow-proof-report.json"))
    });
    paths.sort();
    Ok(paths)
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant