Repository navigation
Conversation
PR Summary by QodoDefine selective entity CEL evaluation and bounded actor-role reuse
AI Description
Diagram
High-Level Assessment
Files changed (12)
|
|
🤖 Finished Review · ✅ Success · Started 8:26 AM UTC · Completed 8:48 AM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $3.18 |
Code Review by Qodo
1. Disabled entity checks look available
|
Site previewPreview: https://bfeca1e0-site.fullsend-ai.workers.dev Commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
<!-- fullsend:risk-assessment --> DetailsDocumentation-only architectural change adding ADRs and normative specifications with low metadata risk and aligned issue scope, moderately elevated to score 2 by large change size and recent churn across shared documentation files. Previous run<!-- fullsend:risk-assessment --> DetailsDocumentation-only architectural change adding ADRs and normative specifications with low metadata risk and aligned issue scope, moderately elevated to score 2 by large change size and recent churn across shared documentation files. Previous run (2)<!-- fullsend:risk-assessment --> DetailsDocumentation-only architectural change adding ADRs and normative specifications with low metadata risk and aligned issue scope, moderately elevated to score 2 by large change size and recent churn across shared documentation files. Previous run (3)<!-- fullsend:risk-assessment --> DetailsDocumentation-only architectural change adding ADRs and normative specifications with low metadata risk and aligned issue scope, moderately elevated by large change size and recent churn across shared documentation files. Previous run (4)<!-- fullsend:risk-assessment --> DetailsDocumentation-only architectural change adding ADRs and normative specifications with low metadata risk and aligned issue scope, moderately elevated by large change size and recent churn across shared documentation files. Previous run (5)<!-- fullsend:risk-assessment --> DetailsDocumentation-only architectural change adding ADRs and normative specifications with low metadata risk and aligned issue scope, moderately elevated by recent churn across shared documentation files. |
ReviewEarlier findings
Previous run<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImZhaWwtb3BlbiIsImZpbGUiOiJkb2NzL25vcm1hdGl2ZS9hdXRob3JpemF0aW9uL3YyL1JFQURNRS5tZCIsImlkIjoiZl84NDYyM2JiYTljOTQ2NjI4IiwibGluZSI6MjI2LCJhY3Rpb25hYmxlIjp0cnVlfSx7InNldmVyaXR5IjoiaW5mbyIsImNhdGVnb3J5Ijoic3RhbGUtZG9jIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL25vcm1hbGl6ZWQtZXZlbnQvdjEvUkVBRE1FLm1kIiwiaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJsaW5lIjoyMSwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzg0NjIzYmJhOWM5NDY2MjgiLCJzdGF0dXMiOiJvcGVuIn0seyJpZCI6ImZfOTc3MmUzMTNkMWMwOGM4MSIsInN0YXR1cyI6InJlY2xhc3NpZmllZCJ9LHsiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJzdGF0dXMiOiJyZXNvbHZlZF9ieV9jaGFuZ2UifV19 --> ReviewFindingsMedium
Earlier findings
Next steps:
Previous run (2)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImZhaWwtb3BlbiIsImZpbGUiOiJkb2NzL25vcm1hdGl2ZS9hdXRob3JpemF0aW9uL3YyL1JFQURNRS5tZCIsImlkIjoiZl84NDYyM2JiYTljOTQ2NjI4IiwibGluZSI6MjI2LCJhY3Rpb25hYmxlIjp0cnVlfSx7InNldmVyaXR5IjoiaW5mbyIsImNhdGVnb3J5Ijoic3RhbGUtZG9jIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL25vcm1hbGl6ZWQtZXZlbnQvdjEvUkVBRE1FLm1kIiwiaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJsaW5lIjoyMSwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJzdGF0dXMiOiJyZWNsYXNzaWZpZWQifSx7ImlkIjoiZl83NTdiM2EzNTg3YmJhMTRlIiwic3RhdHVzIjoicmVzb2x2ZWRfYnlfY2hhbmdlIn1dfQ== --> ReviewFindingsMedium
Earlier findings
Next steps:
Previous run (3)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJhcHByb3ZlIiwiZmluZGluZ3MiOlt7InNldmVyaXR5IjoiaW5mbyIsImNhdGVnb3J5Ijoic3RhbGUtZG9jIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL25vcm1hbGl6ZWQtZXZlbnQvdjEvUkVBRE1FLm1kIiwiaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJsaW5lIjoyMSwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJzdGF0dXMiOiJyZXNvbHZlZF9ieV9jaGFuZ2UifSx7ImlkIjoiZl85NzcyZTMxM2QxYzA4YzgxIiwic3RhdHVzIjoicmVjbGFzc2lmaWVkIn1dfQ== --> Looks good to me Earlier findings
Previous run (4)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfSx7InNldmVyaXR5IjoibG93IiwiY2F0ZWdvcnkiOiJzdGFsZS1kb2MiLCJmaWxlIjoiZG9jcy9ub3JtYXRpdmUvbm9ybWFsaXplZC1ldmVudC92MS9SRUFETUUubWQiLCJpZCI6ImZfOTc3MmUzMTNkMWMwOGM4MSIsImxpbmUiOjIxLCJhY3Rpb25hYmxlIjp0cnVlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJzdGF0dXMiOiJvcGVuIn1dfQ== --> ReviewFindingsMedium
Low
Labels: PR adds ADRs and design documentation Next steps:
Previous run (5)<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6InN0YWxlLWRvYyIsImZpbGUiOiJkb2NzL25vcm1hdGl2ZS9ub3JtYWxpemVkLWV2ZW50L3YxL1JFQURNRS5tZCIsImlkIjoiZl85NzcyZTMxM2QxYzA4YzgxIiwibGluZSI6MjEsImFjdGlvbmFibGUiOnRydWV9XX0= --> ReviewFindingsLow
Next steps:
|
Record selective entity CEL acquisition and bounded actor-role reuse. Set a common verified triage floor for human event, entity-fact, and Fullsend-controlled model admission. Keep stronger harness checks in CEL and document versioned migration prerequisites. Signed-off-by: Barak Korren <bkorren@redhat.com> Assisted-by: Codex (GPT-6)
5006524 to
62c391a
Compare
|
🤖 Finished Review · ✅ Success · Started 9:54 PM UTC · Completed 10:03 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $2.13 |
Apply a role-derived human minimum, configurable per trusted harness, to event, entity CEL, and model-bound record gates. Keep triage as the platform floor and label and bot grants separate. Signed-off-by: Barak Korren <bkorren@redhat.com> Assisted-by: Codex (GPT-6)
|
🤖 Finished Review · ✅ Success · Started 11:48 PM UTC · Completed 11:59 PM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $3.06 |
Superseded by updated review
Acknowledge the v1 role defaults and the merged per-harness Go gate, while keeping configurable and cross-surface policy as the ADR 0151 target. Signed-off-by: Barak Korren <bkorren@redhat.com> Assisted-by: Codex (GPT-6)
Include merged fullsend-ai#8727 per-harness dispatch authorization and its v1 implementation note. Signed-off-by: Barak Korren <bkorren@redhat.com> Assisted-by: Codex (GPT-6)
|
🤖 Finished Review · ✅ Success · Started 12:26 AM UTC · Completed 12:37 AM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $3.03 |
Retroactive record of the decision implemented in PR fullsend-ai#8605 (merged 2026-10-20): hook scripts resolve their interpreter and PATH only from directories the agent cannot write, using the launch loader's trusted-directory rules. Codex hooks fail closed without the trusted environment. Composes with ADR 0094's plugin trust model: the code that registers tools, the code that executes the agent, and the code that observes the agent now all resolve from agent-unwritable space. Renumbered from 0146 to 0150 after checking open PRs for in-flight ADR numbers (0146 = fullsend-ai#8679, 0147 = fullsend-ai#8694, 0148/0149 = fullsend-ai#8698) per the writing-adrs skill's step 1. Signed-off-by: James Tanner <jtanner@redhat.com>
Signed-off-by: Barak Korren <bkorren@redhat.com> Assisted-by: Codex (gpt-6)
|
Added explicit |
|
🤖 Finished Review · ✅ Success · Started 7:17 AM UTC · Completed 7:28 AM UTC Commit: Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $2.46 |
Superseded by updated review
waynesun09
left a comment
There was a problem hiding this comment.
Reviewed ADR 0151 at 9fc06a2c. The decision itself is sound: a non-waivable triage floor, a per-harness human_min_role with a role-derived default, overlays that may only lower it from trusted facts, and the same minimum applied to the prompting event, decisive entity facts and model records. The problem is that the record is hard to read and is pinned to code instead of stating the decision. Three MEDIUM, one LOW.
| [ADR 0061](0061-harness-cel-dispatch.md) puts platform authorization before | ||
| harness CEL. A harness's `role` selects its run identity: GitHub requests a | ||
| mint token for it, while GitLab selects registered role credentials | ||
| ([`run.go` at `fe68925b`](https://github.com/fullsend-ai/fullsend/blob/fe68925b53066c27ba0c0272e2e8eb1ce73ebe40/internal/cli/run.go#L903-L915)). |
There was a problem hiding this comment.
[medium] Context is a code tour pinned to three different commits
Lines 40-67 cite 11 blob/<sha>#L… links across three SHAs (fe68925b, 33dc5e1, c0695aaa), and the Decision adds two more at :153-154. An ADR records a decision; line-pinned links go stale as soon as the code moves, mixing three SHAs means no single "current state" is described, and the reader has to open the code to follow the argument.
The Context only needs to say: authorization runs before CEL and role picks the run identity; v1 thresholds are triage/write; since #8727 CEL dispatch derives the minimum from role, with no explicit field and a label bypass. A possible replacement, with the code evidence moved to the PR description or the implementation issue:
## Context
[ADR 0061](0061-harness-cel-dispatch.md) runs platform authorization before
harness CEL, and a harness's `role` selects its run identity.
[Authorization v1](../normative/authorization/v1/README.md#default-thresholds)
sets `triage` for observation and `write` for mutation; the GitHub bash routes
apply these to slash commands, with an ungated retro-close route as a legacy
exception.
Since #8727, Go CEL dispatch applies a `triage` floor to ordinary human events
and filters candidate harnesses by a default derived from `role` (`triage` and
`review` need `triage`, every other role `write`). The harness schema has no
explicit minimum, and a human label addition bypasses the per-harness
threshold. A single `triage` rule for every harness would let `triage` actors
and records guide a write-capable harness, and a mint token's scopes do not
say which humans may prompt it. ADR 0112 lets trusted-fact overlays set
security-relevant fields, so the minimum must be settable that way too, and
selected before it gates admission.The run-time revision detail (dispatch and run resolving the harness separately) only motivates the second decision below, so it can move with it.
|
|
||
| ## Decision | ||
|
|
||
| For ordinary human actors, Fullsend retains a non-waivable `triage`-level |
There was a problem hiding this comment.
[medium] The Decision restates the contract; keep the decision and link v2
The Decision is about 1,200 words in six dense paragraphs (writing-adrs: "a few paragraphs at most"). Much of it is contract mechanics: overlay layering order (:99-104), guard-evidence and baseline rules (:106-133), and per-check audit behaviour. Authorization Contract v2 in this PR already specifies these gates.
Suggest a short list of the decisions, each one sentence, then "the Authorization Contract v2 specifies the mechanics":
- A non-waivable
triagefloor for ordinary human actors. - Each harness has a
human_min_role: explicit, or derived fromrole(triage/review→triage, everything else →write); allowed values; invalid makes the harness ineligible. - Guarded overlays may set it only from trusted facts, and may only lower the baseline.
- The same minimum applies to the prompting event, decisive actor-originated entity facts, and model-bound records.
- A human label addition is a narrow
triage-equivalent grant, never a role. - Bots are out of scope for
human_min_role.
| fixed within one evaluation or run cycle; a changed policy or guard result | ||
| requires a new cycle or abort, not a silent threshold change. A dispatch or | ||
| poll result is only a candidate selection, not permission to launch. | ||
| The target-repository registry and local harness and `base` files that set |
There was a problem hiding this comment.
[medium] Lines 135-171 are a second decision
This paragraph decides where policy comes from and when it is re-evaluated: one immutable trusted checkout revision, remote layers pinned by content hash, built-in fallbacks resolved per run, and fullsend run reloading config, overlays and trigger CEL and rechecking authorization before context staging or launch. That applies to every CEL/entity run, not only to human_min_role, and it overlaps ADR 0144's per-cycle rule.
Suggest moving it to its own ADR (policy-source integrity and run-time recheck), or into the contract with a one-line pointer here, and dropping the "current behavior is implemented in …" sentence (:152-154) from the Decision.
| - data-security | ||
| --- | ||
|
|
||
| # 151. Use harness human-role minimums for actor admission |
There was a problem hiding this comment.
[low] The file name describes the option this ADR rejects
The slug is common-actor-admission-floor, but the title and decision are per-harness minimums; a common floor is the rejected first option. Renaming to something like 0151-harness-human-role-minimums.md keeps links and search consistent. The Status block (:21-36) could also be a small table (ADR → what changes) so readers see the partial supersession at a glance.
waynesun09
left a comment
There was a problem hiding this comment.
ADRs 0147 and 0148 at 9fc06a2c. Both decisions read as sound. 0148 is clear; 0147 is harder to follow because its Decision also restates 0148 and 0151 and carries poll/run handoff rules. Three MEDIUM, one LOW.
| handoff needs its own retry or rediscovery guarantee. | ||
|
|
||
| Entity routing remains a target design: at | ||
| [`a2be1678`](https://github.com/fullsend-ai/fullsend/blob/a2be1678c5dbd9361a77f04de5ec260320e4fb9f/internal/harness/trigger.go#L12-L16), |
There was a problem hiding this comment.
[medium] Context pins code and carries an implementation-status block
:53-55 cites trigger.go#L12-L16 at a2be1678, and :57-61 is a "Planned" status note. An ADR records the decision; the current state of the code changes and the link goes stale. Suggest one sentence instead, for example: "Entity-source CEL is not implemented yet: the trigger CEL environment declares only event, and the normalized-entity contract (#8420) is still open." The "remains disabled until …" rule is already a Decision sentence at :153-154, so the blockquote can go.
|
|
||
| ## Decision | ||
|
|
||
| Adopt selective, progressive acquisition for entity-source CEL evaluation. |
There was a problem hiding this comment.
[medium] The Decision mixes five topics, two of them owned by sibling ADRs
The Decision is about 720 words in five paragraphs and covers: the selective acquisition plan (:77-93), reuse of fetched data and verified roles within and across checks (:95-109), three-valued results plus the poll→run handoff and retry rules (:111-130), the actor gates (:132-137), and audit contents (:139-148).
Role reuse is ADR 0148's decision and the actor gates are ADR 0151's, so :95-109 and :132-137 restate them; a one-line pointer to each is enough. The handoff and retry rules (:121-130) are not about acquisition either: when a bound run may launch is ADR 0144's lifecycle, and keeping an incomplete candidate retryable across checkpoint advancement is what #8698's ADR 0149 decides for discovery coverage (0149 leaves 0144 in charge of the lifecycle and adds its own retry rule). What remains is the actual decision, which reads well as four sentences:
- Acquire only fields and history that can affect the compiled predicate, and push down only sound filters.
- Results are three-valued; missing, unverifiable or exhausted evidence is
UNKNOWN, never false or empty. - Only decision-relevant facts are authorized and audited; unrelated history is neither fetched nor listed.
- The audit records bounded evidence (scopes, coverage, witness provenance), as specified in Authorization Contract v2.
| human permission result or exact registered-bot-role result across progressive | ||
| iterations, separate checks and harnesses, and `poll` and bound `run` | ||
| processes. A trusted host-owned cache may be local or shared between | ||
| processes. Versioned platform policy must set an explicit maximum age of no |
There was a problem hiding this comment.
[medium] Where does the five-minute bound come from?
The maximum age is the core security trade-off of this ADR: per the consequence at :123-125, an unobserved revocation can still select and launch a sandbox until the entry expires. The ADR fixes it at "no more than five minutes" without saying why five, or what provider load it saves. Please add one sentence on the basis (a measured lookup rate, a provider rate limit, or a matching bound elsewhere), or state that five minutes is a starting value to revisit once entity polling runs. That way a later change to the bound has something to argue against.
| it with their own effective minimum. An exact label-transition grant is not | ||
| an actor-role verdict and cannot be stored in this cache. | ||
|
|
||
| Cache keys and invalidation must isolate the source provider and tenant, |
There was a problem hiding this comment.
[low] The cache-key list is contract detail
:83-87 lists every key dimension (provider, tenant, repository, actor id, permission source, policy revision, source ref, OWNERS, OWNERS_ALIASES, bot registry revision). That is what Authorization Contract v2 is for; the ADR can say "keys isolate the permission source and its revision, and a known change to any of them invalidates the entry" and link v2.
Summary
Record three decisions for entity-source CEL: acquire only data that can affect the predicate (ADR 0147), reuse verified actor roles for a bounded period (ADR 0148), and apply each selected harness's human admission minimum to the prompting event, decision-relevant entity facts, and Fullsend-controlled model records (ADR 0151).
The platform keeps a non-waivable
triage-level floor. The harnessroleselects the run credential identity and supplies a compatibility default for human admission:triageandreviewdefault totriage; every other role, including custom roles, defaults towrite. A trusted top-levelhuman_min_roleor an ADR 0112 guarded overlay may settriage,write,maintain, oradmin. Token scopes andprivilege_levelsdo not infer the human threshold. Trigger CEL may narrow routing after the platform gate.Review focus
human_min_rolemay use only verified trusted facts available before that harness's actor gate. Role-dependent guards require the future versioned verified-effective-role CEL input; rawevent.actor.roleand label grants cannot choose the minimum. The ordered overlay result, guard evidence, and effective minimum are pinned across dispatch and run. ADR 0112's trusted-field check establishes dependencies; reviewers still need to check which truth value selects a lower threshold (for example, an author can choose a fork).triagegrant for its accepted transition and proven projection. At atriageminimum, that projection remains eligible while the same accepted label state is proven, even if the labeler's later role changes. A higher-minimum harness needs the labeler's current verified effective role. Bot label handoffs and registered-bot authorization remain separate. The grant never fabricates a verified actor role or admits model records.human_min_role: triageon a write-capable harness deliberately permits triage actors and records to guide it while its minted capabilities stay the same. That is a reviewed harness policy choice, not an inference from token capabilities.Other changes
UNKNOWNprogression, durable retry or rediscovery, bound-run rechecks, and decision-relevant audit evidence. Raw monotone state can conservatively defer a run without authorizing every historical updater.This PR changes design documents only. Authorization v1 already specifies
triagefor observation andwritefor mutation. The GitHub bash routes implement the built-in thresholds, and #8727 now applies the harnessrole-derived defaults in Go CEL dispatch for ordinary human events before trigger CEL. Thehuman_min_rolefield is target-only until the loader validates and enforces it, including explicit empty values,basecomposition, guarded overlays, and rejection in deprecatedforge:blocks. Current dispatch and run do not share the verified overlay context or policy-identity handoff required by this target contract. Versioned CEL inputs must expose verified effective roles and label-grant provenance separately; the normalized-entity and snapshot v2 contracts are prerequisites for the target entity and model paths. Snapshot v1 retains its historical threshold.Related issues
Related to #8421. #8420 tracks the normalized-entity schema and partial-data contract required before implementation.
Testing
CI=1 make lintpassed on the staged documentation changes.git diff --check origin/main...HEADpassed.Checklist