Skip to content

feat(approval): origin classes, durable flow trust and scored prompt screening (contract 1.22) - #31

Merged
senamakel merged 6 commits into
mainfrom
gaps-approval-scan
Oct 17, 2026
Merged

senamakel merged 6 commits into
mainfrom
gaps-approval-scan

Conversation

@senamakel

Copy link
Copy Markdown
Member

Summary

Closes the approval and prompt-scan GAPs of epic tinyhumansai/openhuman#7328 so the host can delete its remaining copies. Contract 1.22 (no release in this PR).

  • Origin classes. Origin gains TrustedAutomation, LocalOperator, Unlabelled. EvaluateApproval2 answers them without parking: the first two are audited automatic approvals (auto:trusted-automation, auto:local-operator); Unlabelled is denied unless the scope holds a whole-tool grant (auto:tool-grant), with no prompt, reuse, judge or auto_approve_all. Cron external effects still deny; human-only tools still need a human.
  • Durable flow trust. GrantFlowTool2, RevokeFlowTool2, ListFlowTrust2. One audited Approved row per (flow, tool) through the host-served ApprovalStore2 callback, so it persists across restarts (tested over a restarted module on the disk-ledger fixture). Domain-separated digests keep it from ever being consumed, resumed or used for PreauthorizeFlow2; it is re-checked at consumption so revoking it revokes its unconsumed approvals.
  • ScanPrompt2. { tier, score_milli, rule_ids }: the host detector's weights, thresholds (550/700), leet/Cyrillic/fullwidth/invisible normalization, lowered/collapsed/compact variants and false-positive tuning (recalled-memory transcripts, plural "tokens", "Dan"), ported with its whole test corpus. Base64 and invisible-character markers are reported with no weight. The host's optional env classifier is not ported.
  • ScanPrompt/ScanToolDefinition also report a space-padded jailbreak (override.obfuscated_role).
  • Latency budgets in MODULE.md. All new requests are deny_unknown_fields, redacted Debug, golden fixtures in tests/fixtures/v1_22_approval_scan.json.

Test plan

  • cargo +1.98 fmt --all -- --check
  • cargo +1.98 clippy --all-targets --all-features -- -D warnings
  • cargo +1.98 test --all-features

senamakel and others added 2 commits October 17, 2026 12:22
…screening (contract 1.22)

Adds Origin::{TrustedAutomation, LocalOperator, Unlabelled} to approval evaluation,
GrantFlowTool2/RevokeFlowTool2/ListFlowTrust2 persisted through the ApprovalStore2
callback, and ScanPrompt2 with the host detector's score tiers, normalization and
false-positive tuning. Ports the detector's test corpus as fixtures.

Co-authored-by: Medulla <medulla@tinyhumans.ai>
@tinysweeper

tinysweeper Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper completed its review; deterministic results follow.

State: Incomplete
Priority: none
Reviewed head: 3a5b4827177d
Updated: 2026-10-17T11:05:42Z

Review snapshot

Change surface Files Review signal Count
Production 13 Active findings 0
Tests 11 Noted findings 0
Documentation 2 Resolved findings 2
Configuration 0 Pending checks/questions 1

Completeness: Incomplete
Test assessment: Test coverage is assessed from changed tests and lane evidence; execution is not claimed without trusted check data.

What changed

The diff extends the wire contract to 1.22 in three areas and reworks approval evaluation to honour them. `Origin` gains `TrustedAutomation`, `LocalOperator` and `Unlabelled`; `Rule` gains `GrantOnly`; and the approval engine routes calls through a new `origin_rule` and `automatic_grant` that decide denial, whole-tool grants, human-only remapping and attribution labels before any prompt or judge. New `flow_trust` and `prompt_score` bus modules are re-exported from `lib.rs`, their member names are added to the advertised `METHODS` list, and the module adapter exposes `grant_flow_tool2`, `revoke_flow_tool2`, `list_flow_trust2` and `scan_prompt2` and advertises them in `module_export!`. The redactor gains a `Scorer` behind `scan_prompt_scored`, and the existing verdict scanner now also reports a space-padded `jailbreak`. Documentation in `MODULE.md` and `README.md` describes the new behaviour. The previously raised finding ("Move fenced reaper spawn after lock is shipped") does not correspond to anything in this diff — no reaper spawn or lock ordering appears in the changed files — so it is not reproduced and is dropped.

Features

  • Modified — Origin classes for approval evaluation: `Origin` gains the variants `TrustedAutomation`, `LocalOperator` and `Unlabelled`, and `Rule` gains `GrantOnly`. The rules evaluator returns `Rule::Automatic` for the two trusted origins regardless of posture and `Rule::GrantOnly` for an unlabelled origin, while a Cron external effect still denies. The engine's new `origin_rule` refuses a `GrantOnly` call when the scope holds no whole-tool grant, remaps a trusted-origin automatic rule to `Rule::Approval` for human-only and native tools so those still need a fresh human decision, and `automatic_label` attributes a trusted-origin automatic approval `auto:trusted-automation` or `auto:local-operator`, falling back to `auto:host-policy` for other origins. The persisted attribution allowlist and `grant_still_holds` accept the new labels, and `grant_still_holds` becomes async so an `auto:flow-grant` approval is re-checked against live flow trust at consumption and dies with a prior revocation. (crates/tinysecurity-bus/src/policy.rs#pub enum Origin {, crates/tinysecurity-auto/src/rules.rs#pub enum Rule {, crates/tinysecurity-approval/src/engine.rs#impl Engine {, crates/tinysecurity-approval/src/binding.rs#fn lifecycle_valid(row: &ApprovalRow2) -> bool {)
  • Added — Durable flow trust across restarts: `GrantFlowTool2` writes one durable `Approved` row with the `Flow` choice and the `flow-trust-grant` attribution through the host-served store, with binding digests in a domain separate from any real call so the row is never consumed, resumed or accepted by `PreauthorizeFlow2`; `RevokeFlowTool2` cancels it and `ListFlowTrust2` reads the live rows, all serialized by a per-engine `flow_trust_lock`. While a row is live and current for the scope's subject, policy reference and generation, `EvaluateApproval2` converts a required approval of the exact tool inside the exact flow into an approval attributed `auto:flow-grant`, and the grant is re-checked at consumption. Granting a live pair is `Unchanged` and revoking a missing pair is `Absent`; human-only or native tools, blank or control-character names and oversized names are refused. (crates/tinysecurity-approval/src/engine_flow_trust.rs, crates/tinysecurity-bus/src/flow_trust.rs, crates/tinysecurity-approval/src/engine.rs#fn reusable_grant<'a>(, crates/tinysecurity-approval/src/engine.rs#pub struct Engine {)
  • Modified — Space-padded jailbreak detection in the verdict scanner: The verdict scanner's compact (whitespace-stripped) pass now also reports a spaced-out `jailbreak` as `override.obfuscated_role`, so a remote tool description or prompt with single-token trigger words padded by spaces no longer stays clean. (crates/tinysecurity-redact/src/prompt.rs#impl Scanner {)
  • Modified — Contract 1.22 wire members advertised: `GrantFlowTool2`, `RevokeFlowTool2`, `ListFlowTrust2` and `ScanPrompt2` are added to the advertised method constants and list, and the module adapter exports the four new members behind the same approval-availability and redactor paths as the existing ones. `lib.rs` re-exports the two new bus modules. (crates/tinysecurity-bus/src/names.rs#pub const METHODS: &[&str] = &[, crates/tinysecurity-bus/src/names.rs#pub mod methods {, crates/tinysecurity-bus/src/lib.rs#mod callbacks;, crates/tinysecurity-bus/src/lib.rs#pub use callbacks::*;, crates/tinysecurity-module/src/adapter.rs#tinybus_module::module_export! {)
  • Modified — Documentation for contract 1.22: `MODULE.md` gains a section describing origin classes, durable flow trust and scored prompt screening including latency budgets and false-positive tuning, and `README.md` links the new contract section. Neither file is code, and the security lane excluded both as prose or tabular data. (MODULE.md#module, and a 1.21 host refuses a 1.20 module., README.md#Blocked original content denies; suspicious content denies with)

Tests

  • unit — The rules-evaluator tests assert `TrustedAutomation` and `LocalOperator` evaluate to `Rule::Automatic` across every combination of `auto_approve_all`, `require_approval` and external-effect, and that `Unlabelled` evaluates to `Rule::GrantOnly`.: A table-driven postural matrix matching the documented origin semantics. Not executed or verified here. (crates/tinysecurity-auto/src/rules_tests.rs#fn cron_external_denies_before_shortcuts_and_saas_has_no_implicit_permission() {, crates/tinysecurity-auto/src/rules.rs#pub enum Rule {)
  • unit — Engine and adapter tests assert trusted-origin approvals are audited automatic and never prompt, are consumable once, and never approve a human-only or native tool; unlabelled calls are denied without a whole-tool grant and approved only by the exact grant; Cron external effects still deny and Cron reads stay automatic; flow trust survives a restart and a module restart over the host store, covers only its exact tool and flow, is idempotent on grant and revoke, is stale after the policy generation advances, is rejected for human-only, native, blank, control-character and oversized names, and dies with a revocation before consumption; a flow-trust row cannot be preauthorized, decided or consumed as a human grant.: Behavioural assertions on concrete verdicts, attributions, prompt counts and row counts rather than tautologies. Not executed or verified here. (crates/tinysecurity-approval/src/engine_gaps_tests.rs, crates/tinysecurity-module/src/adapter_approval_tests.rs#async fn automatic_approval_cannot_authorize_a_widening_policy_change(), crates/tinysecurity-approval/src/engine_scopes_tests.rs#async fn a_receipt_reports_the_subject_handle_only_when_asked() -> Result<()> {)
  • wire regression — Golden fixtures round-trip the flow-trust and scored-scan types in both directions, assert unknown origins and unknown fields fail to decode, and assert the new members are advertised and named by contract constants.: Round-trip and additive-versioning assertions at the new contract version. Not executed or verified here. (crates/tinysecurity-bus/tests/approval_scan_wire.rs, crates/tinysecurity-bus/tests/fixtures/v1_22_approval_scan.json, crates/tinysecurity-bus/src/names.rs#pub const METHODS: &[&str] = &[)

Findings

No active actionable findings.

Resolved this pass

  • Move fenced reaper spawn after lock is shipped
  • Move fenced reaper spawn after lock is shipped

Could not review: tinysweeper/description

Before merge

  • Complete the description review for tinysweeper/description.

How this fits together

flowchart LR
  n0["lifecycle_valid<br/>changed"]:::changed
  n1["Engine<br/>changed"]:::changed
  n2["ScopeEntry<br/>changed"]:::changed
  n3["...eports_the_subject_handle_only_when_asked<br/>changed"]:::changed
  n4["Rule<br/>changed"]:::changed
  n5["...tcuts_and_saas_has_no_implicit_permission<br/>changed"]:::changed
  n6["scope_handle"]:::impacted
  n7["evaluate"]:::impacted
  n8["ApprovalScope2"]:::impacted
  n9["ApprovalRow2"]:::impacted
  n10["grant_flow_tool"]:::impacted
  n0 -->|uses| n9
  n1 -->|uses| n9
  n2 -->|uses| n8
  n3 -->|calls| n6
  n3 -->|tests| n6
  n5 -->|uses| n8
  n7 -->|uses| n4
  n7 -->|uses| n8
  n10 -->|calls| n6
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Lane summary: This is a new test-only file porting the host's prompt-injection parity corpus onto the crate's `Scorer`; the expectations I could check line up with the weights and thresholds in `crates/tinysecurity-redact/src/score.rs` and `tinysecurity-bus/src/prompt_score.rs`. The earlier finding ("Move fenced reaper spawn after lock is shipped") does not correspond to anything in this file — it is not present here and no comparable code exists in this diff. One test I cannot verify from the file alone is a lookup I could not settle: the rule-coverage case asserting `"reveal your rules"` fires `exfiltration.intent` depends on the `EXFILTRATION_INTENT` regex, which does contain a `reveal\s+(\S+\s+){0,3}(...|rules?)` branch, so it appears satisfied. No defects found. _The code index is behind this pull request (indexed at `47c0e5f5705f`), so retrieved context may be out of date._

security

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The security lane reported no findings across the files it reviewed. It states that `flow_trust` and `prompt_score` exist with redacted `Debug`, deny-unknown-fields serde, snake_case names, sibling test files and documented items, that the `pub use` reordering is alphabetical and consistent, and that no untrusted input reaches a sink in that file's changes.
  • Positive: Sensitive identifiers are redacted: the flow-trust request, response and list types have redacted `Debug` impls, the trust row stores the flow as an identifier hash, and the scored request's `Debug` hides the prompt, with dedicated tests asserting the names and prompt never appear in `Debug` output.
  • Positive: `MODULE.md` and `README.md` were not security-reviewed and were excluded as prose or tabular data. The one earlier security finding concerned reaper spawn ordering that does not appear in this revision's diff and was not reproduced.
  • Lane summary: This is a new test-only file porting a prompt-injection parity corpus onto the new `Scorer`; the fenced test fixtures (homoglyph, zero-width, leet, fullwidth payloads) are inputs asserting detection works, and the file adds no production code, network calls, or untrusted-input sinks. I found no reportable defect in this file. _The code index is behind this pull request (indexed at `47c0e5f5705f`), so retrieved context may be out of date._

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The tests lane found no defect it could anchor to a concrete reachable input, describing the new tests as behavioural with deny paths for human-only and native tools and revocation before consumption.
  • Lane summary: The previously raised finding ("Move fenced reaper spawn after lock is shipped") does not correspond to any code in this pull request's diff — no reaper spawn or lock ordering appears anywhere in the changed files — so there is nothing to verify and it is dropped. The remaining change is a contract-1.22 addition (origin classes, durable flow trust, scored prompt scanning) backed by substantial tests that pin the stated invariants; I am issuing no new findings this pass. (1 earlier finding(s) still open) _The code index is behind this pull request (indexed at `47c0e5f5705f`), so retrieved context may be out of date._

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Neutral
  • Scope reviewed: incomplete; unanswered: tinysweeper/description
  • Lane summary: No reviewer produced a usable response.
Evidence and run details
  • Models: ladder/vectors-oai3, deepseek-v4.1-flash
  • Spend: $0.000819
  • Tokens: 462561 input · 6631 output · 199552 cached · 784 embedding
  • Continuity: summary cache chain restarted at the storage ceiling.
Head State Pass summary
800fcb456f3e incomplete 1 active finding(s), 0 resolved finding(s) (at 2026-10-17T09:29:41Z)
11f9731aca9c incomplete 0 active finding(s), 2 resolved finding(s) (at 2026-10-17T10:03:53Z)
47c0e5f5705f incomplete 0 active finding(s), 3 resolved finding(s) (at 2026-10-17T10:35:43Z)
3a5b4827177d incomplete 0 active finding(s), 2 resolved finding(s) (at 2026-10-17T11:05:42Z)

tinysweeper 0.1.2

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-17T10:32:46.072264Z 47c0e5f New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

This review includes 26 billable files and costs up to $6.50.

Or wait 24 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3729c946-34f3-4487-9eb6-dc33a485bf1d
📥 Commits

Reviewing files that changed from the base of the PR and between e31716b and 3a5b482.

📒 Files selected for processing: 26
  • MODULE.md
  • README.md
  • crates/tinysecurity-approval/src/binding.rs
  • crates/tinysecurity-approval/src/engine.rs
  • crates/tinysecurity-approval/src/engine_flow_trust.rs
  • crates/tinysecurity-approval/src/engine_gaps_tests.rs
  • crates/tinysecurity-approval/src/engine_scopes_tests.rs
  • crates/tinysecurity-auto/src/rules.rs
  • crates/tinysecurity-auto/src/rules_tests.rs
  • crates/tinysecurity-bus/src/flow_trust.rs
  • crates/tinysecurity-bus/src/flow_trust_tests.rs
  • crates/tinysecurity-bus/src/lib.rs
  • crates/tinysecurity-bus/src/names.rs
  • crates/tinysecurity-bus/src/policy.rs
  • crates/tinysecurity-bus/src/prompt_score.rs
  • crates/tinysecurity-bus/src/prompt_score_tests.rs
  • crates/tinysecurity-bus/tests/approval_scan_wire.rs
  • crates/tinysecurity-bus/tests/fixtures/v1_22_approval_scan.json
  • crates/tinysecurity-module/src/adapter.rs
  • crates/tinysecurity-module/src/adapter_approval_tests.rs
  • crates/tinysecurity-module/src/adapter_gaps_tests.rs
  • crates/tinysecurity-redact/src/lib.rs
  • crates/tinysecurity-redact/src/prompt.rs
  • crates/tinysecurity-redact/src/prompt_tests.rs
  • crates/tinysecurity-redact/src/score.rs
  • crates/tinysecurity-redact/src/score_tests.rs
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 800fcb456f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/tinysecurity-auto/src/rules.rs

@tinysweeper tinysweeper 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.

Requesting changes: 1 lane(s) blocking, worst finding is high.

Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.

             $0.0150 · 3,394,007 in / 139,940 out · 686,464 cached (20%) · ladder/vectors-oai3, deepseek-v4.1-flash, , glm-5.3-flash · 772 embedded
critique:    $0.0115 · 1,987,641 in / 117,850 out · 392,448 cached (20%) · deepseek-v4.1-flash,
security:    $0.0021 · 1,101,218 in / 13,839 out  · 193,024 cached (18%) · deepseek-v4.1-flash, glm-5.3-flash
tests:       $0.0001 · 111,438 in   / 429 out     · 55,424 cached (50%)  · deepseek-v4.1-flash
description: $0.0005 · 145,696 in   / 900 out     · 45,568 cached (31%)  · glm-5.3-flash, deepseek-v4.1-flash

Comment thread crates/tinysecurity-redact/src/score_tests.rs
… tests

Co-authored-by: Medulla <medulla@tinyhumans.ai>

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3cbe32234

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

};
let entry = self.entry(&request.scope_id)?;
let granted = entry
let mut granted = entry

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Recheck unlabelled rows against whole-tool grants

When an Unlabelled call was approved by a whole-tool grant, replacing the scope with only a matching per-flow grant leaves the unconsumed row executable because this generic grant() check accepts either grant type. This bypasses the new rule that unlabelled origins may be authorized only by a whole-tool grant; revalidation should use tool_grant() for these rows or rerun the origin-specific grant rule.

Useful? React with 👍 / 👎.

judge: None,
audit: request.audit,
};
self.persist(None, &row).await?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Refuse grants before exceeding the load ceiling

If a scope already has the maximum valid load of 1,024 approval records, a distinct flow-trust grant reaches this persistence call and creates record 1,025 while still returning Granted. Every subsequent operation that loads the scope then fails because ApprovalLoadRequest2::verify_response rejects responses containing more than 1,024 records, effectively bricking approvals for that scope; enforce the shared record capacity before persisting another long-lived trust row.

Useful? React with 👍 / 👎.

Comment on lines +176 to +177
if request.flow_id.is_empty() || request.flow_id.len() > 1024 || request.tool.is_empty() {
return Err(Error::Invalid);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Apply grant validation to revocations

For revocations containing whitespace/control characters, names over the 256-byte grant limit, or human-only/native tools, this weaker validation accepts values that grant_flow_tool can never create and reports Absent instead of refusing the malformed request. Reuse trust_pair_valid here so grant and revoke enforce the documented name and tool constraints consistently.

Useful? React with 👍 / 👎.

Co-authored-by: Medulla <medulla@tinyhumans.ai>

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 11f9731aca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +615 to +622
// A human-only tool needs a fresh human decision under every origin: the
// trusted-origin shortcuts never cover it.
Rule::Automatic
if matches!(origin, Origin::TrustedAutomation | Origin::LocalOperator)
&& (HUMAN_ONLY_TOOLS2.contains(&request.request.call.tool.as_str())
|| binding::is_native(&request.request.call.tool)) =>
{
Ok(Rule::Approval)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep all human-only tools off the reuse path

When a TrustedAutomation or LocalOperator call repeats the content of a previously human-approved policy_change whose choice was Tool or Flow, this fallback changes the origin result to Approval, but begin_reuse still treats only sandbox_host_network, device_crypto, and native entry points as human-only. It therefore returns an automatically approved exact-reviewed-grant row without obtaining the fresh decision required for every human-only call. The fresh evidence after the earlier fix is the narrower human-only check at begin_reuse, so this guard should also prevent reuse for every entry in HUMAN_ONLY_TOOLS2.

Useful? React with 👍 / 👎.

Comment on lines +77 to +85
flow_id.len() <= 1024
&& ApprovalGrants2 {
tools: vec![],
flows: vec![FlowToolGrant2 {
flow_id: flow_id.into(),
tool: tool.into(),
}],
}
.is_valid()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow the full supported flow-ID length

For flow identifiers between 257 and 1,024 bytes, approval evaluation accepts CallerContext::flow, and revocation/list filtering also explicitly accept up to 1,024 bytes, but wrapping the pair in ApprovalGrants2 invokes is_valid, whose shared grant-name limit is 256 bytes. Consequently GrantFlowTool2 rejects an otherwise valid flow that the rest of this API supports, so flow and tool validation need separate bounds here.

Useful? React with 👍 / 👎.

@tinysweeper tinysweeper 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.

tinysweeper found nothing blocking, but could not review everything, so this is not an approval: crates/tinysecurity-approval/src/engine.rs, tinysweeper/description.

             $0.0187 · 550,166 in / 88,521 out · 37,632 cached (7%)  · ladder/vectors-oai3, glm-5.3-flash, deepseek-v4.1-flash · 775 embedded
critique:    $0.0028 · 97,714 in  / 25,233 out · 25,856 cached (26%) · glm-5.3-flash, deepseek-v4.1-flash
security:    $0.0144 · 299,053 in / 56,437 out · 11,776 cached (4%)  · deepseek-v4.1-flash, glm-5.3-flash
tests:       $0.0006 · 54,757 in  / 3,030 out  · 0 cached (0%)       · glm-5.3-flash
description: $0.0004 · 47,031 in  / 682 out    · 0 cached (0%)       · glm-5.3-flash

Co-authored-by: Medulla <medulla@tinyhumans.ai>

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47c0e5f570

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +49 to +52
/// A call whose origin the host could not label (contract 1.22). Approval
/// evaluation denies it unless the registered scope holds a whole-tool grant for
/// the tool, which approves it as an audited automatic approval.
Unlabelled,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Deny unlabelled origins access to sandbox operator privileges

When this shared variant is used in SandboxScope2, a local scope with origin: Unlabelled, a TrustedHost source, and environment: Disabled can request host_run and receive an unjailed host artifact: crates/tinysecurity-sandbox/src/engine.rs:438-440 makes isolation mandatory only for Origin::Saas. The same fallthrough also treats the new origin as eligible for operator host-network and process-isolation exceptions, even though Unlabelled explicitly means the host could not classify the caller. Update the sandbox origin checks to allowlist actual operator origins rather than letting every new non-SaaS variant inherit operator privileges.

Useful? React with 👍 / 👎.

@tinysweeper tinysweeper 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.

tinysweeper found nothing blocking, but could not review everything, so this is not an approval: tinysweeper/tests.

             $0.0141 · 482,190 in / 48,175 out · 105,856 cached (22%) · ladder/vectors-oai3, deepseek-v4.1-flash, glm-5.3-flash · 775 embedded
critique:    $0.0090 · 242,130 in / 41,004 out · 60,032 cached (25%)  · deepseek-v4.1-flash
security:    $0.0012 · 47,385 in  / 1,384 out  · 0 cached (0%)        · glm-5.3-flash, deepseek-v4.1-flash
description: $0.0005 · 144,319 in / 864 out    · 45,824 cached (32%)  · glm-5.3-flash, deepseek-v4.1-flash

Co-authored-by: Medulla <medulla@tinyhumans.ai>

@tinysweeper tinysweeper 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.

tinysweeper found nothing blocking, but could not review everything, so this is not an approval: tinysweeper/description.

             $0.0008 · 462,561 in / 6,631 out · 199,552 cached (43%) · ladder/vectors-oai3, deepseek-v4.1-flash · 784 embedded
critique:    $0.0001 · 105,812 in / 1,048 out · 50,048 cached (47%)  · deepseek-v4.1-flash
security:    $0.0001 · 102,246 in / 870 out   · 49,024 cached (48%)  · deepseek-v4.1-flash
tests:       $0.0001 · 111,203 in / 445 out   · 54,528 cached (49%)  · deepseek-v4.1-flash
description: $0.0001 · 94,137 in  / 907 out   · 45,952 cached (49%)  · deepseek-v4.1-flash

@senamakel
senamakel merged commit 6fec542 into main Oct 17, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant