Skip to content

docs(flows): fix contract-drift comments and repair the workflow-builder prompt structure - #5290

Merged
graycyrus merged 1 commit into
tinyhumansai:mainfrom
graycyrus:docs/flows-contract-drift
Jul 31, 2026
Merged

docs(flows): fix contract-drift comments and repair the workflow-builder prompt structure#5290
graycyrus merged 1 commit into
tinyhumansai:mainfrom
graycyrus:docs/flows-contract-drift

Conversation

@graycyrus

@graycyrus graycyrus commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes seven comments/docs that asserted invariants the code does not hold — the same drift class that let several real bugs survive earlier review.
  • Repairs a structural break in the workflow_builder prompt where steps 3–6 of the authoring loop rendered as if they belonged to a different section.
  • Makes the prompt regression pins wrap-insensitive, so a semantically neutral reflow can no longer break the suite (they previously matched exact hard-wrapped substrings).
  • Adds a drift test that derives the tool table mechanically, so the module doc cannot silently rot again.

Problem

Documentation in this area had drifted far enough to actively mislead both humans and agents:

  • prompt.md — "## Your authoring loop" opened a numbered list (1, 2), then three full H2 sections were wedged in, so steps "3. Build the graph" … "6. Debugging a broken saved flow" rendered under Inference provider readiness.
  • builder_prompt.rs — 49 pin assertions matched exact hard-wrapped substrings, several spanning a specific wrap column. Any reflow of prompt.md broke the suite for no semantic reason, which discourages exactly the prompt maintenance the file needs.
  • prompt.rs — a near-tautological test (body.contains("propose")) that cannot meaningfully fail.
  • builder_tools.rs — the module doc table listed 11 of ~22 tools, gave DryRunWorkflowTool the wrong permission, and asserted "the agent still cannot create a flow" directly above CreateWorkflowTool. A second stale "cannot create" claim also sat inside SaveWorkflowTool's own doc.
  • agents/mod.rs — still claimed workflow_builder "never persists", though save_workflow / create_workflow / duplicate_flow are all on its belt.
  • caps.rshttp_cred_name claimed "No host-side HTTP credential store exists yet", while HttpCredentialsStore is load-bearing immediately below it.
  • store.rs — the prune doc listed only completed/failed/cancelled, but the SQL (NOT IN ('running','pending_approval')) also prunes interrupted and completed_with_warnings.
  • DryRunWorkflowTool.security — a dead field, never read, whose doc claimed tier-gating that both permission_level() and the pinned dry_run_allowed_under_readonly_tier test contradict.

Solution

  • Moved the three interleaved H2 sections below the complete 6-step loop — a pure content move, no wording changes — and verified the resulting document order end to end.
  • Routed every STANDING_PROMPT.contains(...) assertion through a whitespace-normalizing helper. Every assertion's intent is unchanged; only the comparison is now wrap-insensitive. The pins for Rejecting a seeded flow build leaves the graph persisted #4596 auto-save, B27 phantom review card, Bld §4 offer-then-refuse, and the self-DM platform_user_id rule all still pin exactly what they did.
  • Deleted the tautological test (real, falsifiable coverage of the same invariant already lives in builder_prompt.rs) and justified it in a comment.
  • Rewrote the tool table from all 22 actual impl Tool for registrations, removed the dead security field and its stale doc, and corrected the remaining false claims.
  • Added module_doc_tool_table_matches_registered_tools, which derives the tool list from impl Tool for matches in the same source file — no hardcoded second list — and asserts both directions. This turns a recurring manual problem into a mechanical one.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — mostly doc/comment lines (not instrumented); the code changes (dead-field removal, pin normalization, new drift test) are covered. cargo test --lib "openhuman::flows::" = 549 passed, 0 failed
  • Coverage matrix updated — N/A: documentation + dead-code removal, no feature rows added/removed/renamed
  • All affected feature IDs from the matrix are listed under ## RelatedN/A: no matrix feature rows affected
  • No new external network dependencies introduced
  • Manual smoke checklist updated if this touches release-cut surfaces — N/A: no runtime behaviour change
  • Linked issue closed via Closes #NNNN/A: found by code review, no tracking issue filed yet

Impact

  • Runtime/platform: Rust core. The only behavioural change is the removal of a dead, never-read field; everything else is docs, prompt structure, and tests.
  • Prompt: the workflow_builder standing prompt is restructured (content move only), so the model now reads a coherent 6-step authoring loop instead of steps 3–6 apparently nested under an unrelated section.
  • Maintenance: prompt edits no longer break pins on reflow, and the tool table is now self-checking.
  • Migration/security: none.

Related

  • Closes: N/A
  • Follow-up PR(s)/TODOs: the standing prompt is ~30k tokens with several rules stated 2–4× in different sections — a deliberate slimming pass (deduplicate to one canonical statement each, push per-kind reference detail into the contract tools it already defers to) is worth doing separately, with these pins as the safety net.
  • Merge order: overlaps builder_tools.rs + builder_tools_tests.rs with the authorization-boundaries PR, and store.rs with the resume-lifecycle PR. Merge this one last of the three; it rebases cleanly.

AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: docs/flows-contract-drift
  • Commit SHA: 52e9f5bbe

Validation Run

  • pnpm --filter openhuman-app format:check — N/A, no frontend files changed
  • pnpm typecheck — N/A, no TypeScript changed
  • Focused tests: GGML_NATIVE=OFF cargo test --lib "openhuman::flows::"549 passed, 0 failed (incl. openhuman::flows::agents 23, builder_tools 91, store 34; tinyflows::caps 112 run separately for the doc-only change there)
  • Rust fmt/check (if changed): GGML_NATIVE=OFF cargo check clean; rustfmt --check clean on all touched files
  • Tauri fmt/check (if changed): N/A, app/src-tauri untouched

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: none at runtime, apart from removing a dead field. The prompt's rendered structure changes (steps 3–6 now read as part of the authoring loop).
  • User-visible effect: none directly; the builder agent reads a correctly-structured prompt.

Parity Contract

  • Legacy behavior preserved: every prompt pin retains its original intent — only the string comparison is normalized. No prompt wording was changed, only section order.
  • Guard/fallback/dispatch parity checks: dry_run_allowed_under_readonly_tier still passes after the dead-field removal, confirming the tool's gating posture is genuinely unchanged.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): none
  • Canonical PR: this one
  • Resolution: N/A

Summary by CodeRabbit

  • Documentation
    • Clarified workflow authoring, persistence, duplication, and save behavior.
    • Documented the expanded workflow-builder toolkit and dry-run availability.
    • Clarified terminal run cleanup statuses and credential-reference handling.
  • Bug Fixes
    • Dry runs are now available without security-policy gating.
    • Improved prompt checks to remain reliable across whitespace and line wrapping.
  • Tests
    • Added coverage ensuring all registered workflow tools are documented accurately.

…t the actual code (PR I)

Zero behaviour change except where noted (T-m1). Findings from
my_docs/flows_review_2026-07-30.md / _FIXPLAN.md:

- P-m1: prompt.md's "## Your authoring loop" opened a numbered list (steps
  1-2) then wedged three full H2 sections in before steps 3-6, so the tail of
  the loop rendered as if it belonged to "Inference provider readiness".
  Moved the three H2 sections below the complete authoring loop.

- P-m4 (coupled with P-m1): builder_prompt.rs's STANDING_PROMPT regression
  tests asserted exact hard-wrapped substrings of prompt.md, which the P-m1
  reflow would otherwise break. Added a whitespace-normalizing
  contains_normalized() helper and routed every STANDING_PROMPT assertion
  through it, preserving each assertion's original intent (auto-save tinyhumansai#4596,
  phantom review card B27, offer-then-refuse Bld §4, self-DM
  platform_user_id, etc.) while making the suite resilient to future
  semantically-neutral rewraps.

- P-m5: deleted prompt.rs's near-tautological
  prompt_teaches_the_propose_never_persist_invariant test
  (body.contains("propose") is true regardless of correctness — the word
  appears dozens of times regardless of whether the invariant actually
  holds). Real, falsifiable coverage of the propose-only contract already
  lives in builder_prompt.rs (create_prompt_frames_propose_only,
  build_is_propose_only_and_injects_flow_id_as_context, and the
  standing_prompt_* tests), so this was redundant rather than strengthened.

- T-m1 (code change): DryRunWorkflowTool.security was written but never
  read, and its doc claimed "Autonomy-tier gated ... read-only tier
  refuses" while permission_level() returns None and
  dry_run_allowed_under_readonly_tier pins the opposite. Removed the dead
  field/constructor param (and the now-unused SecurityPolicy import + test
  policy() helper), updated the one call site in tools/ops.rs and all 21
  test call sites, and rewrote the doc to state the actual (intentional,
  F7) ungated contract.

- T-m2: builder_tools.rs's module-doc table listed 11 of 22 tools, gave
  DryRunWorkflowTool the wrong permission, and claimed "the agent still
  cannot *create* a flow" directly above CreateWorkflowTool. Rewrote the
  table from the actual `impl Tool for` registrations, fixed the same stale
  "no tool to create a flow" claim inside SaveWorkflowTool's own doc, and
  fixed flows/agents/mod.rs's workflow_builder doc which still said the
  agent "never persists" despite create_workflow/duplicate_flow/
  save_workflow being on its belt.

- E-m7: tinyflows/caps.rs's http_cred_name doc claimed "No host-side HTTP
  credential store exists yet" — false; HttpCredentialsStore exists and is
  load-bearing in the very next function (resolve_http_credential).
  Corrected.

- R-m9: flows/store.rs's prune_flow_runs_conn doc said it deletes
  completed/failed/cancelled rows, but the SQL (status NOT IN ('running',
  'pending_approval')) also prunes interrupted and completed_with_warnings.
  The code was right; fixed the comment to match.

- Optional (T-m2 follow-up): added
  module_doc_tool_table_matches_registered_tools, a mechanical drift guard
  that derives the tool list straight from `impl Tool for` in the same
  source file (no hardcoded second list to go stale) and fails if the
  module-doc table and the registered tools ever diverge again, in the
  spirit of propose_workflow_description_matches_typed_node_contracts.

Verified: GGML_NATIVE=OFF cargo check, cargo test --lib
openhuman::flows::agents (23 passed), cargo test --lib
openhuman::flows::builder_tools (91 passed, incl. the new drift test),
plus openhuman::flows::store and openhuman::tinyflows::caps for the
doc-only E-m7/R-m9 changes. No Cargo.toml/Cargo.lock changes.
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c7343aca-291d-4b1a-a94f-10cd13dbf902

📥 Commits

Reviewing files that changed from the base of the PR and between bb83836 and 52e9f5b.

📒 Files selected for processing (9)
  • src/openhuman/flows/agents/mod.rs
  • src/openhuman/flows/agents/workflow_builder/builder_prompt.rs
  • src/openhuman/flows/agents/workflow_builder/prompt.md
  • src/openhuman/flows/agents/workflow_builder/prompt.rs
  • src/openhuman/flows/builder_tools.rs
  • src/openhuman/flows/builder_tools_tests.rs
  • src/openhuman/flows/store.rs
  • src/openhuman/tinyflows/caps.rs
  • src/openhuman/tools/ops.rs

📝 Walkthrough

Walkthrough

The PR updates workflow-builder documentation and prompt guidance, makes prompt regression checks whitespace-insensitive, removes SecurityPolicy from dry-run construction, and adds documentation-drift coverage. It also clarifies flow-run pruning and HTTP credential-reference behavior.

Changes

Workflow builder contracts

Layer / File(s) Summary
Prompt guidance and assertions
src/openhuman/flows/agents/...
The authoring loop now includes construction, dry-run verification, validation, proposal, revision, and debugging. Prompt tests normalize whitespace while preserving behavioral assertions.
Dry-run tool contract and registration
src/openhuman/flows/builder_tools.rs, src/openhuman/tools/ops.rs
DryRunWorkflowTool now accepts only configuration. Documentation identifies dry runs as ungated and documents the complete tool surface.
Dry-run regression and documentation checks
src/openhuman/flows/builder_tools_tests.rs
Tests use the configuration-only constructor and verify that registered tools match the module documentation.
Runtime documentation contracts
src/openhuman/flows/store.rs, src/openhuman/tinyflows/caps.rs
Documentation covers all pruneable terminal statuses and host-side HTTP credential resolution with fail-closed handling.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested labels: rust-core

Suggested reviewers: m3ga-mind

Poem

A rabbit checks each prompt in line,
Whitespace smooths the wording fine.
Dry runs hop with no guard’s key,
Tool docs match their registry.
Flows stay drafts until commands say,
“Save this work,” on a careful day.


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

@greptile-apps greptile-apps 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.

graycyrus has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.

@graycyrus
graycyrus merged commit 7d7fb48 into tinyhumansai:main Jul 31, 2026
22 of 24 checks passed
@coderabbitai coderabbitai Bot added the rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. label Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant