Skip to content

docs(adr): define selective CEL acquisition and harness admission - #8694

Open
ifireball wants to merge 7 commits into
fullsend-ai:mainfrom
ifireball:codex/selective-cel-acquisition-adr
Open

ifireball wants to merge 7 commits into
fullsend-ai:mainfrom
ifireball:codex/selective-cel-acquisition-adr

Conversation

@ifireball

@ifireball ifireball commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

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 harness role selects the run credential identity and supplies a compatibility default for human admission: triage and review default to triage; every other role, including custom roles, defaults to write. A trusted top-level human_min_role or an ADR 0112 guarded overlay may set triage, write, maintain, or admin. Token scopes and privilege_levels do not infer the human threshold. Trigger CEL may narrow routing after the platform gate.

Review focus

  • The same resolved minimum applies separately to event actors, actor-originated facts that could make entity CEL actionable, and each Fullsend-controlled model-bound record at its fresh exposure checkpoint. A prompting actor or CEL match does not authorize another record.
  • An overlay setting human_min_role may use only verified trusted facts available before that harness's actor gate. Role-dependent guards require the future versioned verified-effective-role CEL input; raw event.actor.role and 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).
  • A human label addition supplies an exact, provider-proven triage grant for its accepted transition and proven projection. At a triage minimum, 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.
  • An explicit human_min_role: triage on 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.
  • The registry and local harness policy come from a trusted immutable revision (the target/base commit for change proposals), with hash-verified remote layers. Dispatch binds the composed policy identity, overlay outcome, and effective minimum to the run handoff; run verifies the same policy before using credentials or content. Actor-role caches hold verified roles, not per-harness pass decisions; each harness reapplies its own minimum.

Other changes

  • ADR 0147 defines selective acquisition, UNKNOWN progression, 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.
  • ADR 0148 permits scoped actor-role reuse for entity CEL, with an absolute five-minute cap, known-change invalidation, and rechecks after cache-dependent false decisions. Event and model-bound checks remain fresh.
  • Authorization Contract v2 defines the gates, narrow label grants, overlay selection order, and audit evidence. Accepted ADRs receive short status cross-references; architecture and related problem documents reflect the target decision.

This PR changes design documents only. Authorization v1 already specifies triage for observation and write for mutation. The GitHub bash routes implement the built-in thresholds, and #8727 now applies the harness role-derived defaults in Go CEL dispatch for ordinary human events before trigger CEL. The human_min_role field is target-only until the loader validates and enforces it, including explicit empty values, base composition, guarded overlays, and rejection in deprecated forge: 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 lint passed on the staged documentation changes.
  • git diff --check origin/main...HEAD passed.
  • Tests not applicable: documentation only.

Checklist

  • PR title follows Conventional Commits.
  • Commits have one DCO sign-off and agent attribution.
  • I wrote this contribution myself and can explain all changes in it.

@ifireball
ifireball requested a review from a team as a code owner October 22, 2026 08:24
@ifireball ifireball self-assigned this Oct 22, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Define selective entity CEL evaluation and bounded actor-role reuse

📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Adopt progressive entity-data acquisition so CEL checks need not read unrelated history.
• Permit provider-verified actor-role reuse for entity CEL, capped at five minutes.
• Version the authorization contract while keeping entity-source CEL disabled pending a partial-data
 contract.
Diagram

graph TD
  A["Event or poll"] --> B["Origin gate"] --> C["Selective plan"] --> D["Authorized facts"] --> E{"CEL result"}
  E -- "true" --> F["Bound recheck"] --> G["Sandbox launch"]
  H["Role cache"] --> D
  E -- "UNKNOWN: acquire" --> C
  E -- "false: reconcile" --> A
  F -- "inconclusive: retry" --> C
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Require complete entity history before CEL
  • ➕ Simpler completeness reasoning and full-history audit reconstruction.
  • ➖ Reads, authorizes, and audits unrelated records even for state-only or short-circuiting predicates.
2. Refresh actor roles on every check
  • ➕ Recognizes provider-side permission changes at the next check.
  • ➖ Repeats lookups across progressive iterations, poll cycles, and bound runs.

Recommendation: The proposed combination is appropriate for reducing provider load while explicitly bounding uncertainty and stale-role risk. Keep entity-source CEL disabled until the normalized-entity contract can express partial data, source coverage, and concurrency; retain fresh event-admission and model-bound gates.

Files changed (12) +1061 / -18

Documentation (12) +1061 / -18
config.tsExpose normative specifications in the docs sidebar +5/-0

Expose normative specifications in the docs sidebar

• Adds a sidebar section that discovers documents under docs/normative, making the versioned authorization contracts easier to find.

docs/.vitepress/config.ts

0063-polling-based-work-discovery.mdClarify retry requirements for entity-source handoffs +5/-0

Clarify retry requirements for entity-source handoffs

• Links ADR 0147's durable retry or proven rediscovery requirement while preserving the legacy reconstructed-event lastCheck rule.

docs/ADRs/0063-polling-based-work-discovery.md

0098-entity-first-harness-evaluation.mdMark entity-evaluation guarantees partially superseded +10/-1

Mark entity-evaluation guarantees partially superseded

• Identifies the full-history, audit-roster, and per-evaluation role-refresh rules revised by ADRs 0147 and 0148. Clarifies that trusted-origin, event-actor, and model-bound gates remain required.

docs/ADRs/0098-entity-first-harness-evaluation.md

0144-reuse-poll-and-entity-bound-run-processes.mdDistinguish retained process rules from revised check rules +7/-0

Distinguish retained process rules from revised check rules

• Marks complete-entity due checks, full-history audits, and per-check role refresh as partially superseded without changing lifecycle, scheduling, or model-bound authorization rules.

docs/ADRs/0144-reuse-poll-and-entity-bound-run-processes.md

0147-evaluate-entity-cel-over-selectively-acquired-data.mdAdopt selective, progressive entity CEL acquisition +159/-0

Adopt selective, progressive entity CEL acquisition

• Defines conservative dependency planning, partial-data UNKNOWN semantics, coverage proofs, actor-gated facts, and provisional poll-to-run handoffs with retry guarantees. Replaces full-history audit rosters with bounded decision evidence and keeps entity-source CEL disabled pending a normalized-entity contract.

docs/ADRs/0147-evaluate-entity-cel-over-selectively-acquired-data.md

0148-reuse-verified-actor-roles-for-entity-cel.mdAdopt bounded reuse of verified CEL actor roles +120/-0

Adopt bounded reuse of verified CEL actor roles

• Permits scoped provider-verified role reuse across checks and processes with an absolute five-minute maximum, known-change invalidation, and rechecks after cache-dependent false results. Preserves fresh event and model-bound authorization, and documents the possible stale-grant sandbox-launch window.

docs/ADRs/0148-reuse-verified-actor-roles-for-entity-cel.md

architecture.mdAlign architecture and observability guidance with the ADRs +33/-15

Align architecture and observability guidance with the ADRs

• Replaces full-history entity-check guidance with selective acquisition, coverage-aware outcomes, bounded role reuse, and decision-focused audit evidence. Clarifies the remaining normalized-entity contract prerequisite.

docs/architecture.md

README.mdIdentify v1 as the retained dispatch contract +9/-1

Identify v1 as the retained dispatch contract

• Links to v2 and explains which future entity-evaluation and audit requirements it supersedes. States that existing event-backed dispatch continues using v1 until migration.

docs/normative/authorization/v1/README.md

README.mdSpecify Authorization Contract v2 +703/-0

Specify Authorization Contract v2

• Defines normative rules for selective acquisition, coverage, actor attribution, UNKNOWN outcomes, durable handoffs, bounded audit evidence, and scoped actor-role caching. Preserves separate event-actor and model-bound gates and documents migration and versioning boundaries.

docs/normative/authorization/v2/README.md

agent-architecture.mdLink entity-centric architecture to the new decisions +4/-0

Link entity-centric architecture to the new decisions

• Adds references to progressive entity acquisition and bounded verified-role sharing in the entity-trigger discussion.

docs/problems/agent-architecture.md

agent-infrastructure.mdQualify role sharing across repeated entity checks +1/-1

Qualify role sharing across repeated entity checks

• Connects resident process reuse to ADR 0148's bounded actor-role lifetime.

docs/problems/agent-infrastructure.md

operational-observability.mdConnect entity-trigger audits to bounded evidence +5/-0

Connect entity-trigger audits to bounded evidence

• References decision-relevant provenance and source-coverage evidence, including the age of shared actor-role results used for CEL.

docs/problems/operational-observability.md

@fullsend-ai-review

fullsend-ai-review Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 8:26 AM UTC · Completed 8:48 AM UTC

Commit: 5006524 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $3.18

@qodo-code-review

qodo-code-review Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (1)

Grey Divider


Informational

1. Disabled entity checks look available 📜 Skill insight ≡ Correctness
Description
The added documentation describes entity-source CEL as disabled or not yet implemented without the
required > **Planned:** callout or an issue link. Readers of the ADR and normative contract
therefore cannot distinguish this future behavior from current functionality, and the same omission
appears in the v2 entity-evaluation section.
Code

docs/ADRs/0147-evaluate-entity-cel-over-selectively-acquired-data.md[R135-136]

+Entity-source CEL remains disabled until a versioned normalized-entity
+contract defines partial data, coverage, and concurrency semantics.
Relevance

● Weak

Similar planned-feature callout findings in normative and user docs were rejected by authors.

PR-#6083
PR-#8275
PR-#6035

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance rule requires every mention of a not-yet-implemented feature to use a `>
**Planned:**` blockquote with a relevant issue link. The new ADR explicitly says entity-source CEL
remains disabled until a future contract exists, while the v2 contract states that the path is not
yet implemented; neither changed section uses that callout or provides an issue link.

docs/ADRs/0147-evaluate-entity-cel-over-selectively-acquired-data.md[132-136]
docs/normative/authorization/v2/README.md[285-300]
Skill: writing-user-docs

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new documentation mentions that entity-source CEL is disabled until the normalized-entity contract exists, but it does not use the required planned-feature callout or link to the relevant issue. Similar future-state wording appears in the Authorization Contract v2 entity-evaluation section.

## Fix Focus Areas
- docs/ADRs/0147-evaluate-entity-cel-over-selectively-acquired-data.md[135-136]
- docs/normative/authorization/v2/README.md[294-300]

## Recommended Fix
Rewrite each not-yet-implemented feature reference as a `> **Planned:**` blockquote and include a link to the relevant tracking issue, such as #8420 for the normalized-entity and partial-data contract. Ensure the wording clearly distinguishes planned behavior from currently implemented functionality.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Dismiss ↗ | View ↗


Grey Divider

Context sources
✅ Compliance rules (platform): 95 rules
✅ Skills: 5 invoked
  writing-user-docs
  writing-adrs
  check-patch-coverage
  cutting-releases
  adr-corner
✅ Cross-repo context — repo relationships
  Explored: repo: fullsend-ai/experiments (sha: 09c2dbc2) — View relationship
  Explored: repo: fullsend-ai/agents (sha: a41950c1) — View relationship
Review mode: Auto: ⚖️ Balanced: Security-sensitive normative contract with broad cross-document authorization implications.

Grey Divider

Tip of the day
💡 Did you know, you can enable the Remediation agent and Qodo fixes findings in a dedicated fix PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@github-actions

github-actions Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Site preview

Preview: https://bfeca1e0-site.fullsend-ai.workers.dev

Commit: 9fc06a2c6e0403511853634e78964e78b2fe359c

@codecov

codecov Bot commented Oct 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fullsend-ai-review fullsend-ai-review Bot added the risk/moderate PR risk: moderate label Oct 22, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

<!-- fullsend:risk-assessment -->
Risk Assessment: moderate (2/5)

Details

Documentation-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 -->
Risk Assessment: moderate (2/5)

Details

Documentation-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 -->
Risk Assessment: moderate (2/5)

Details

Documentation-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 -->
Risk Assessment: moderate (2/5)

Details

Documentation-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 -->
Risk Assessment: moderate (2/5)

Details

Documentation-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 -->
Risk Assessment: moderate (2/5)

Details

Documentation-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.

@fullsend-ai-review

fullsend-ai-review Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Review

Earlier findings

  • docs/normative/authorization/v2/README.md:226, fail-open: resolved. Overlays may now only preserve or lower the non-overlay baseline, a known-absent guard leaves the baseline in place, and ADR 0151 now requires a conditional relaxation to positively prove its trusted condition.
  • docs/normative/normalized-event/v1/README.md:21, stale-doc: still open at info severity. The file was not touched since the prior review, so this is not resolved.
Previous run

<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImZhaWwtb3BlbiIsImZpbGUiOiJkb2NzL25vcm1hdGl2ZS9hdXRob3JpemF0aW9uL3YyL1JFQURNRS5tZCIsImlkIjoiZl84NDYyM2JiYTljOTQ2NjI4IiwibGluZSI6MjI2LCJhY3Rpb25hYmxlIjp0cnVlfSx7InNldmVyaXR5IjoiaW5mbyIsImNhdGVnb3J5Ijoic3RhbGUtZG9jIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL25vcm1hbGl6ZWQtZXZlbnQvdjEvUkVBRE1FLm1kIiwiaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJsaW5lIjoyMSwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzg0NjIzYmJhOWM5NDY2MjgiLCJzdGF0dXMiOiJvcGVuIn0seyJpZCI6ImZfOTc3MmUzMTNkMWMwOGM4MSIsInN0YXR1cyI6InJlY2xhc3NpZmllZCJ9LHsiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJzdGF0dXMiOiJyZXNvbHZlZF9ieV9jaGFuZ2UifV19 -->

Review

Findings

Medium

  • [fail-open] docs/normative/authorization/v2/README.md:226 — A known-absent event or optional guard key is still treated as an overlay nonmatch (as ADR 0112 specifies), so a harness that raises human_min_role only in an overlay silently falls back to the weaker inherited minimum when the guard key is missing. For example, a harness defaults to write and its overlay requires admin only when an optional trusted config key is set. If that key is absent, write applies. Required-but-unavailable guard metadata and CEL errors already fail closed. The guidance that avoids this pattern (put the strictest minimum at the top level and use overlays only to lower it, with a guard that positively proves the trusted condition) is a SHOULD, not a MUST. The latest push does not change this text.
    Remediation: Make it normative that the strictest applicable minimum is the fallback and that an overlay may only lower it on positively verified guard evidence. Alternatively, reject at validation any overlay that raises human_min_role, so a missing guard key can never select a weaker minimum.

Earlier findings

  • docs/normative/authorization/v2/README.md:592, permission-expansion — resolved earlier; no further action.
  • docs/normative/normalized-event/v1/README.md:21, stale-doc — reclassified (info, below the posting threshold): the file is modified by this PR, and the Authorization v1 statement at that line still describes current event-backed dispatch accurately.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (2)

<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6ImZhaWwtb3BlbiIsImZpbGUiOiJkb2NzL25vcm1hdGl2ZS9hdXRob3JpemF0aW9uL3YyL1JFQURNRS5tZCIsImlkIjoiZl84NDYyM2JiYTljOTQ2NjI4IiwibGluZSI6MjI2LCJhY3Rpb25hYmxlIjp0cnVlfSx7InNldmVyaXR5IjoiaW5mbyIsImNhdGVnb3J5Ijoic3RhbGUtZG9jIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL25vcm1hbGl6ZWQtZXZlbnQvdjEvUkVBRE1FLm1kIiwiaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJsaW5lIjoyMSwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJzdGF0dXMiOiJyZWNsYXNzaWZpZWQifSx7ImlkIjoiZl83NTdiM2EzNTg3YmJhMTRlIiwic3RhdHVzIjoicmVzb2x2ZWRfYnlfY2hhbmdlIn1dfQ== -->

Review

Findings

Medium

  • [fail-open] docs/normative/authorization/v2/README.md:226 — Under ADR 0112 a known-absent event or optional key is an overlay nonmatch, and the contract keeps that rule for overlays that set human_min_role (v2 README lines 226-229; ADR 0151 lines 100-102). If a harness author puts the stricter minimum in a guarded overlay (for example admin when a trusted config flag is true or an event field is present) and leaves a weaker top-level or default minimum such as write, a known-absent guard input selects the weaker value. During eventless entity discovery that weaker value also admits other actors' facts. The contract steers authors away from this only with a SHOULD (lines 216-221; ADR 0151 lines 106-111) and does not forbid the escalate-on-present pattern. The triage platform floor still bounds the outcome, and this affects the proposed design only, not current enforcement.
    Remediation: Pick one: (a) require the strongest potentially applicable minimum at the top level and allow overlays only to relax it on positively verified conditions; or (b) require that overlays which raise human_min_role deny evaluation, rather than fall back, when their guard inputs are known-absent. Mirror the change in ADR 0151.

Earlier findings

  • docs/normative/normalized-event/v1/README.md:21, stale-doc, reclassified — the Authorization Contract v1 statement for the event-backed path remains accurate while v1 stays in force, and the delta adds a v2 human_min_role cross-reference at line 293; informational only.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (3)

<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJhcHByb3ZlIiwiZmluZGluZ3MiOlt7InNldmVyaXR5IjoiaW5mbyIsImNhdGVnb3J5Ijoic3RhbGUtZG9jIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL25vcm1hbGl6ZWQtZXZlbnQvdjEvUkVBRE1FLm1kIiwiaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJsaW5lIjoyMSwiYWN0aW9uYWJsZSI6ZmFsc2V9LHsic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJzdGF0dXMiOiJyZXNvbHZlZF9ieV9jaGFuZ2UifSx7ImlkIjoiZl85NzcyZTMxM2QxYzA4YzgxIiwic3RhdHVzIjoicmVjbGFzc2lmaWVkIn1dfQ== -->

Looks good to me

Earlier findings

  • docs/normative/authorization/v2/README.md:592, permission-expansion, resolved: the rewritten model-bound admission section (around lines 725–736) now enforces the selected harness's human_min_role per record, rather than unconditional triage admission.
  • docs/normative/normalized-event/v1/README.md:21, stale-doc, reclassified to info: the sentence is still accurate, because v1 retains its entity-discovery rows and its new version note supersedes only the full-history evaluation and audit requirements. The remaining gap is an optional pointer to Authorization Contract v2.
Previous run (4)

<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InBlcm1pc3Npb24tZXhwYW5zaW9uIiwiZmlsZSI6ImRvY3Mvbm9ybWF0aXZlL2F1dGhvcml6YXRpb24vdjIvUkVBRE1FLm1kIiwiaWQiOiJmXzc1N2IzYTM1ODdiYmExNGUiLCJsaW5lIjo1OTIsImFjdGlvbmFibGUiOmZhbHNlfSx7InNldmVyaXR5IjoibG93IiwiY2F0ZWdvcnkiOiJzdGFsZS1kb2MiLCJmaWxlIjoiZG9jcy9ub3JtYXRpdmUvbm9ybWFsaXplZC1ldmVudC92MS9SRUFETUUubWQiLCJpZCI6ImZfOTc3MmUzMTNkMWMwOGM4MSIsImxpbmUiOjIxLCJhY3Rpb25hYmxlIjp0cnVlfV0sImRpc3Bvc2l0aW9ucyI6W3siaWQiOiJmXzk3NzJlMzEzZDFjMDhjODEiLCJzdGF0dXMiOiJvcGVuIn1dfQ== -->

Review

Findings

Medium

  • [permission-expansion] docs/normative/authorization/v2/README.md:592 — The common model-record floor lets a triage-only contributor supply mutation instructions to a write-capable harness even when its trigger CEL requires a write-authorized prompting actor (e.g., a triage-level comment requesting a code change before a maintainer triggers the coder). ADR 0133 lets admitted records carry task instructions, so no hidden text or detectable injection is needed. ADR 0151 acknowledges this trade-off, but no record-level stronger threshold or endorsement mechanism offsets it. This is a design decision for human maintainers rather than an automatic fix.
    Remediation: Allow a harness or platform policy to set a stronger per-record task-guidance threshold independent of trigger CEL, or require write authority (or a write-authorized endorsement bound to the exact record revision) before lower-privilege content can direct mutations.

Low

  • [stale-doc] docs/normative/normalized-event/v1/README.md:21 — Lines 21–22 still say "Authorization Contract v1 also defines the trusted-origin gate for future entity discovery." This PR adds Authorization Contract v2, which now also defines the trusted-origin gate and says it supersedes v1's future entity-evaluation requirements. The cross-reference sends readers of future entity discovery only to v1 and is now incomplete. The file is unchanged by this PR.
    Remediation: Update lines 21–22 to also point to Authorization Contract v2 for future entity discovery, or note that v2 supersedes v1's future entity-evaluation requirements.

Labels: PR adds ADRs and design documentation


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR
Previous run (5)

<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJsb3ciLCJjYXRlZ29yeSI6InN0YWxlLWRvYyIsImZpbGUiOiJkb2NzL25vcm1hdGl2ZS9ub3JtYWxpemVkLWV2ZW50L3YxL1JFQURNRS5tZCIsImlkIjoiZl85NzcyZTMxM2QxYzA4YzgxIiwibGluZSI6MjEsImFjdGlvbmFibGUiOnRydWV9XX0= -->

Review

Findings

Low

  • [stale-doc] docs/normative/normalized-event/v1/README.md:21 — This unchanged file says "Authorization Contract v1 also defines the trusted-origin gate for future entity discovery." The sentence is still literally true. But this PR adds Authorization Contract v2, which ADR 0147 adopts, and v2 supersedes v1's future full-history entity-evaluation and audit requirements. v2 also restates the trusted-origin gate for poll discovery and bound-run eventless recheck, so a reader sent only to v1 for future entity discovery misses the governing contract.
    Remediation: Point the future entity-discovery sentence to Authorization Contract v2 (adopted by ADR 0147, with ADR 0148 for bounded role reuse). Keep v1 as the reference for the current event-backed path.

Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

Comment thread docs/normative/authorization/v2/README.md Outdated
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)
@ifireball
ifireball force-pushed the codex/selective-cel-acquisition-adr branch from 5006524 to 62c391a Compare October 22, 2026 21:52
@ifireball ifireball changed the title docs(adr): define selective entity CEL and bounded role reuse docs(adr): define selective CEL acquisition and actor floor Oct 22, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:54 PM UTC · Completed 10:03 PM UTC

Commit: 62c391a · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $2.13

fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review fullsend-ai-review Bot added type/adr component/docs User-facing documentation labels Oct 22, 2026
@ifireball
ifireball requested a review from waynesun09 October 22, 2026 22:22
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)
@fullsend-ai-review

fullsend-ai-review Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 11:48 PM UTC · Completed 11:59 PM UTC

Commit: 7b549b7 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $3.06

@fullsend-ai-review fullsend-ai-review Bot removed the ready-for-merge All reviewers approved — ready to merge label Oct 22, 2026
fullsend-ai-review[bot]

This comment was marked as outdated.

@fullsend-ai-review
fullsend-ai-review Bot dismissed their stale review October 22, 2026 23:59

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)
@fullsend-ai-review

fullsend-ai-review Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 12:26 AM UTC · Completed 12:37 AM UTC

Commit: e083d47 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $3.03

fullsend-ai-review[bot]

This comment was marked as outdated.

Comment thread docs/normative/authorization/v2/README.md Outdated
Comment thread docs/ADRs/0147-evaluate-entity-cel-over-selectively-acquired-data.md Outdated
jctanner added a commit to jctanner-fullsend-ai/fullsend that referenced this pull request Oct 23, 2026
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)
@ifireball

Copy link
Copy Markdown
Member Author

Added explicit > **Planned:** callouts in ADR 0147 and Authorization v2, each linking to issue #8420. They state that entity-source CEL remains disabled until its normalized-entity contract and the required evaluator/authorization gates are implemented, and clarify that legacy non-CEL, non-entity workflows remain under Authorization v1.

@fullsend-ai-review

fullsend-ai-review Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:17 AM UTC · Completed 7:28 AM UTC

Commit: 9fc06a2 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $2.46

@fullsend-ai-review
fullsend-ai-review Bot dismissed stale reviews from themself October 25, 2026 07:28

Superseded by updated review

@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label Oct 25, 2026
@ifireball
ifireball requested a review from waynesun09 October 26, 2026 12:07

@waynesun09 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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)).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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":

  1. A non-waivable triage floor for ordinary human actors.
  2. Each harness has a human_min_role: explicit, or derived from role (triage/review → triage, everything else → write); allowed values; invalid makes the harness ineligible.
  3. Guarded overlays may set it only from trusted facts, and may only lower the baseline.
  4. The same minimum applies to the prompting event, decisive actor-originated entity facts, and model-bound records.
  5. A human label addition is a narrow triage-equivalent grant, never a role.
  6. 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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 waynesun09 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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:

  1. Acquire only fields and history that can affect the compiled predicate, and push down only sound filters.
  2. Results are three-valued; missing, unverifiable or exhausted evidence is UNKNOWN, never false or empty.
  3. Only decision-relevant facts are authorized and audited; unrelated history is neither fetched nor listed.
  4. 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

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[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.

This branch was successfully deployed

2 active deployments
site-preview — 9fc06a2c Deployed Oct 25, 2026 by github-actions[bot]
dev — 9fc06a2c Deployed Oct 25, 2026 by ifireball via playback #17894
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/docs User-facing documentation ready-for-merge All reviewers approved — ready to merge risk/moderate PR risk: moderate type/adr

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants