Skip to content

feat: implement issue #1404 — [Phase 2] Author a machine-readable interaction contract for every agentic role, per the standard - #1418

Merged
don-petry merged 6 commits into
mainfrom
dev-lead/issue-1404-20260802-0151
Aug 2, 2026
Merged

don-petry merged 6 commits into
mainfrom
dev-lead/issue-1404-20260802-0151

Conversation

@don-petry

@don-petry don-petry commented Aug 2, 2026 •

Copy link
Copy Markdown
Collaborator

User description

Closes #1404

Implemented by dev-lead agent. Please review.


CodeAnt-AI Description

Add machine-readable interaction contracts and validate them in CI

What Changed

  • Added interaction contracts for personas and runtime agents, documenting triggers, outputs, idempotency, concurrency, stop markers, and automation budgets
  • Added a hermetic validator that checks contract structure, workflow paths, timer requirements, allowed values, declared outputs, and direct self-trigger risks
  • CI now validates every interaction contract and runs dedicated coverage for valid, invalid, missing, and malformed contracts
  • Validation failures report a concise error instead of exposing a traceback

Impact

✅ Fewer misconfigured agent workflows
✅ Earlier detection of self-triggering automation
✅ Clearer CI errors for invalid interaction contracts

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • Added interaction contracts for runtime workflows and supported personas.
    • Defined triggers, responses, scheduling, concurrency, idempotency, stop conditions, and automation budgets.
    • Added safeguards against duplicate, recursive, or unsafe automation activity.
    • Added validation for contract structure, workflow references, timers, event handling, and self-trigger protection.
  • Tests

    • Added comprehensive coverage for valid, malformed, incomplete, and unsafe contracts.
  • Chores

    • Integrated contract validation into lint CI with pinned, reproducible dependencies.

…eraction contract for every agentic role, per the standard
@don-petry
don-petry requested a review from a team as a code owner August 2, 2026 02:08
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@codeant-ai

codeant-ai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR f5bb8dc Aug 02, 2026 · 02:08 02:09

@coderabbitai

coderabbitai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds machine-readable contracts for eight personas and three runtimes. It adds a standalone YAML validator, hermetic Bats coverage, and a pinned CI job for interaction-contract changes.

Changes

Interaction contract definitions

Layer / File(s) Summary
Runtime contracts and guard rules
interaction-contracts/ci-failure-analyst.yml, interaction-contracts/dev-lead.yml, interaction-contracts/pr-review.yml
Defines runtime workflows, triggers, timers, emissions, self-trigger guards, idempotency, concurrency, stop markers, and budgets.
Persona contracts
personas/*/interaction.yml
Defines persona metadata, workflow bindings, deployed triggers, emissions, idempotency keys, concurrency lanes, stop markers, and budgets.

Contract validation and CI

Layer / File(s) Summary
Validator implementation
interaction-contracts/validate-interaction-contracts.py
Discovers contracts and validates YAML structure, workflow paths, triggers, timers, emissions, self-trigger guards, idempotency, concurrency, stop markers, and budgets.
Hermetic validation tests
tests/test_validate_interaction_contracts.bats
Tests valid contracts, malformed fields, workflow paths, timers, emissions, self-trigger rules, runtime contracts, and YAML parse errors.
Lint workflow integration
.github/workflows/lint.yml
Adds interaction-contract path filtering, includes the Bats test, and runs the validator with pinned PyYAML.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant LintWorkflow
  participant Validator
  participant Repository
  LintWorkflow->>Validator: Run contract validation
  Validator->>Repository: Read interaction-contract YAML files
  Validator->>Validator: Check schema, timers, emits, guards, and workflow paths
  Validator-->>LintWorkflow: Report success or validation error
Loading

Possibly related PRs

Suggested labels: needs-human-review

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds the required contracts, validator, and tests, but dev-lead.yml omits live self-trigger emits and explicit guards required by issue #1404. Update interaction-contracts/dev-lead.yml to declare the live self-trigger emits with matching self_trigger_guards, or document an approved deferral before merge.
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The workflow, contract, validator, and test changes directly support issue #1404 and introduce no unrelated code.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the implementation of machine-readable interaction contracts for every agentic role, which matches the pull request's primary change.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev-lead/issue-1404-20260802-0151

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

❤️ Share

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

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Aug 2, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add per-role interaction contracts and hermetic CI validation gate

✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add machine-readable interaction contracts for all persona and runtime roles.
• Introduce a hermetic validator enforcing §8.1 shape and safety invariants (e.g., no self-trigger).
• Gate CI on contract validity via new workflow job and Bats test coverage.
Diagram

graph TD
  A["GitHub Actions: lint.yml"] --> B["Job: validate-interaction-contracts"] --> C["validate-interaction-contracts.py"] --> D["persona contracts\n(personas/*/interaction.yml)"] --> G["CI status"]
  C --> E["runtime contracts\n(interaction-contracts/*.yml)"] --> G
  C --> F["Workflow files\n(.github/workflows/*)"] --> G
  subgraph Legend
    direction LR
    _ci["CI Job"] ~~~ _tool["Validator Script"] ~~~ _data["Contract YAML"]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. JSON Schema + jsonschema validation
  • ➕ Clear, formally versioned schema with strong typing and reusable tooling
  • ➕ Better error localization for nested shape violations
  • ➖ Adds dependency/tooling weight; may complicate the “fully hermetic, no schema fetch” constraint
  • ➖ Would still need custom logic for semantic invariants (workflow existence, self-trigger rules)
2. Embed contracts into persona.yml / workflow annotations
  • ➕ Fewer files; co-locates metadata with the primary configuration source
  • ➕ Potentially simpler discovery (single source per role)
  • ➖ Reintroduces coupling to persona schema/versioning and cross-repo schema concerns the PR explicitly avoids
  • ➖ Harder to represent runtime/deployment lenses that aren’t personas (e.g., ring-0 caller stubs + backstop timers)

Recommendation: Keep the PR’s current approach: standalone YAML contracts plus a small hermetic validator. It matches the stated design goal (no network/schema fetch), cleanly supports both persona and runtime lenses, and enforces key safety invariants early in CI. If validation needs grow, consider layering jsonschema only for structural checks while retaining custom Python checks for invariants.

Files changed (14) +878 / -0

Enhancement (12) +624 / -0
ci-failure-analyst.ymlAdd runtime interaction contract for ci-failure-analyst +31/-0

Add runtime interaction contract for ci-failure-analyst

• Introduces a deployment-lens contract describing the ci-failure-analyst runtime triggers (check_run) and emitted comment marker, including idempotency and concurrency lane semantics.

interaction-contracts/ci-failure-analyst.yml

dev-lead.ymlAdd runtime/deployment interaction contract for dev-lead +53/-0

Add runtime/deployment interaction contract for dev-lead

• Adds a runtime-lens contract covering dev-lead.yml and dev-lead-retry.yml, including the self-heal cron timer metadata (role, justification, stop_condition, event_fast_path) and declared emits/stop markers/budget.

interaction-contracts/dev-lead.yml

pr-review.ymlAdd runtime/deployment interaction contract for pr-review +46/-0

Add runtime/deployment interaction contract for pr-review

• Adds a runtime-lens contract folding pr-review-trigger fast path with pr-review-sweep backstop timer, documenting triggers, emits, idempotency, concurrency lanes, stop markers, and budget.

interaction-contracts/pr-review.yml

validate-interaction-contracts.pyIntroduce hermetic interaction contract validator +197/-0

Introduce hermetic interaction contract validator

• Adds a Python validator that discovers persona and runtime contracts, parses YAML, enforces required fields/types, validates enums (kind, budget, timer roles), ensures referenced workflow files exist, and checks a narrow self-trigger prohibition for emits vs subscribed events.

interaction-contracts/validate-interaction-contracts.py

interaction.ymlAdd persona interaction contract for business-analyst +36/-0

Add persona interaction contract for business-analyst

• Defines the persona-lens contract for mention-routed business-analyst, documenting deployed triggers via persona-mention router and the advisory comment emission with idempotency and concurrency lanes.

personas/business-analyst/interaction.yml

interaction.ymlAdd persona interaction contract for dev-lead +44/-0

Add persona interaction contract for dev-lead

• Defines the role-lens contract for dev-lead’s event subscriptions and outputs, explicitly separate from the runtime/deployment lens in interaction-contracts/dev-lead.yml.

personas/dev-lead/interaction.yml

interaction.ymlAdd persona interaction contract for devops-lead +36/-0

Add persona interaction contract for devops-lead

• Defines mention-routed advisory triggers and emitted advisory comment behavior, including idempotency key and concurrency lane conventions.

personas/devops-lead/interaction.yml

interaction.ymlAdd persona interaction contract for pr-review +37/-0

Add persona interaction contract for pr-review

• Defines the role-lens contract for pr-review’s event surface (excluding manual workflow_dispatch) and emitted review/comment markers, plus idempotency/concurrency and budget/stop markers.

personas/pr-review/interaction.yml

interaction.ymlAdd persona interaction contract for qa-lead +36/-0

Add persona interaction contract for qa-lead

• Defines mention-routed advisory triggers through persona-mention and the advisory comment output with idempotency and concurrency semantics.

personas/qa-lead/interaction.yml

interaction.ymlAdd persona interaction contract for scrum-master +36/-0

Add persona interaction contract for scrum-master

• Defines mention-routed advisory triggers and advisory comment emission, including stop marker and budget none.

personas/scrum-master/interaction.yml

interaction.ymlAdd persona interaction contract for security-lead +36/-0

Add persona interaction contract for security-lead

• Defines mention-routed advisory triggers and the single advisory comment emission, with idempotency/concurrency and stop marker.

personas/security-lead/interaction.yml

interaction.ymlAdd persona interaction contract for sre-lead +36/-0

Add persona interaction contract for sre-lead

• Defines mention-routed advisory triggers and advisory comment emission, documenting idempotency key, concurrency lane, stop marker, and budget none.

personas/sre-lead/interaction.yml

Tests (1) +229 / -0
test_validate_interaction_contracts.batsAdd hermetic Bats coverage for contract validator +229/-0

Add hermetic Bats coverage for contract validator

• Adds fixture-based tests covering acceptance of valid contracts and rejection of key invariant violations (missing fields, bad enums, missing workflows, empty emits, timer requirements, and self-trigger dispatch). Ensures parse errors are reported without a traceback.

tests/test_validate_interaction_contracts.bats

Other (1) +25 / -0
lint.ymlGate CI on interaction-contract validation +25/-0

Gate CI on interaction-contract validation

• Extends workflow path filters to include interaction-contracts/. Adds a new validate-interaction-contracts job that installs PyYAML and runs the hermetic validator, and wires the new Bats test into the lint test list.

.github/workflows/lint.yml

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — review-changes (no-changes)

No changes were needed for this PR.

@don-petry
don-petry enabled auto-merge (squash) August 2, 2026 02:09
Comment thread interaction-contracts/validate-interaction-contracts.py Outdated
Comment thread interaction-contracts/validate-interaction-contracts.py Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces machine-readable interaction contracts for various agentic roles along with a Python validation script (validate-interaction-contracts.py) and a BATS test suite to verify their well-formedness. The review feedback suggests aligning the Python script with PEP 8 by moving the yaml import to the top level and removing redundant local imports/checks. Additionally, the BATS test suite should be updated to use $BATS_TEST_TMPDIR for automatic cleanup instead of manual directory creation and teardown.

Comment thread tests/test_validate_interaction_contracts.bats Outdated
Comment thread tests/test_validate_interaction_contracts.bats Outdated
Comment thread interaction-contracts/validate-interaction-contracts.py
Comment thread interaction-contracts/validate-interaction-contracts.py Outdated
Comment thread interaction-contracts/validate-interaction-contracts.py Outdated
@don-petry
don-petry disabled auto-merge August 2, 2026 02:10
@qodo-code-review

qodo-code-review Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 48 rules

Grey Divider


Remediation recommended

1. Unpinned PyYAML install ✓ Resolved 🐞 Bug ☼ Reliability
Description
The new validate-interaction-contracts job installs PyYAML via pip3 install ... pyyaml without a
version pin or wheel-only constraint, making CI behavior non-reproducible and more prone to
transient PyPI/source-build failures. This repo already documents and guards against this exact
failure mode in other workflows/tests.
Code

.github/workflows/lint.yml[R333-335]

+      - name: Install PyYAML
+        run: pip3 install --quiet pyyaml
+
Relevance

●●● Strong

Team has accepted pinning PyYAML installs in workflows to avoid CI flakiness and drift.

PR-#284
PR-#276

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new job installs PyYAML unpinned. Repo tests describe prior flakiness from unpinned PyPI
installs/source builds and enforce pinning/wheel-only patterns elsewhere, indicating this is a known
reliability risk pattern.

.github/workflows/lint.yml[316-337]
tests/test_test_workflow_resilience.sh[5-16]
tests/test_test_workflow_resilience.sh[86-107]
tests/aw/test_test_aw_yml.sh[4-12]
tests/aw/test_test_aw_yml.sh[48-52]
PR-#1366

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 `validate-interaction-contracts` job installs PyYAML without pinning or `--only-binary`, which can introduce CI flakiness and non-reproducible behavior.

### Issue Context
Repo tests already call out PyYAML/PyPI fetch flakiness and require pinning + wheel-only in other workflows.

### Fix Focus Areas
- .github/workflows/lint.yml[333-335]

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


2. Permissive emits token check ✓ Resolved 🐞 Bug ≡ Correctness
Description
validate-interaction-contracts.py treats commit and push as prefixes, so invalid tokens like
commitment/pushy would incorrectly pass emits validation. This weakens the well-formedness gate
by allowing malformed emits entries through CI.
Code

interaction-contracts/validate-interaction-contracts.py[R153-155]

+        if not emit.startswith(EMIT_PREFIXES):
+            fail(f"{path}: interaction.emits entry '{emit}' must start with one of "
+                 f"{list(EMIT_PREFIXES)} so its produced event class is declared")
Relevance

●●● Strong

Repo often tightens validation/regex guards to reject malformed inputs; permissive startswith checks
get hardened.

PR-#683
PR-#1366

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The allowed-prefix tuple includes bare commit/push, and the enforcement uses startswith(),
which will match arbitrary longer strings that begin with those substrings.

interaction-contracts/validate-interaction-contracts.py[40-44]
interaction-contracts/validate-interaction-contracts.py[151-155]

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 validator uses `startswith()` against a tuple that includes bare `commit` and `push`, which unintentionally accepts any longer string beginning with those substrings.

### Issue Context
This validator is meant to be a strict well-formedness gate for interaction contracts; accepting malformed emits tokens undermines the gate.

### Fix Focus Areas
- interaction-contracts/validate-interaction-contracts.py[40-44]
- interaction-contracts/validate-interaction-contracts.py[151-155]

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


3. Docs/validator emits mismatch ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The validator rejects emits entries using the comment-marker: prefix even though the normative
schema example in docs/agentic-interaction-model.md uses comment-marker: in §8.1. This creates
an immediate standard-vs-CI mismatch where a contract can be “correct per docs” but fail validation.
Code

interaction-contracts/validate-interaction-contracts.py[43]

+EMIT_PREFIXES = ("label:", "comment:", "review:", "dispatch:", "commit", "push")
Relevance

●●● Strong

They routinely align docs/examples with enforced validators to avoid immediate docs-vs-CI
mismatches.

PR-#367
PR-#1289

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Docs §8.1 shows comment-marker: as a valid emits token prefix, but the validator only allows
comment: (via EMIT_PREFIXES) and enforces this via startswith(EMIT_PREFIXES), so
comment-marker: would fail CI.

docs/agentic-interaction-model.md[372-396]
interaction-contracts/validate-interaction-contracts.py[40-44]
interaction-contracts/validate-interaction-contracts.py[151-155]

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 validator’s allowed emits prefixes do not match the documented schema example (`comment-marker:`), creating confusion and potential false failures.

### Issue Context
Docs are marked normative and explicitly define the schema shape in §8.1.

### Fix Focus Areas
- interaction-contracts/validate-interaction-contracts.py[40-44]
- interaction-contracts/validate-interaction-contracts.py[151-155]
- docs/agentic-interaction-model.md[372-396]

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


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread .github/workflows/lint.yml
Comment thread interaction-contracts/validate-interaction-contracts.py Outdated
Comment thread interaction-contracts/validate-interaction-contracts.py Outdated
donpetry-bot
donpetry-bot previously approved these changes Aug 2, 2026

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: f5bb8dc87651a7b838270b13755198cada5a9d3d
Review mode: triage-approved (single reviewer)

Summary

Additive change implementing Story 2 / #1404: machine-readable interaction contracts for all 8 personas (personas/<id>/interaction.yml) and 3 non-persona runtimes (interaction-contracts/*.yml), plus a hermetic well-formedness validator, a 13-case bats suite, and a new validate-interaction-contracts job in lint.yml. The triage assessment holds: no deletions, no secrets, workflow-level permissions: contents: read, and the new job's actions/checkout pin 3d3c42e5aac5ba805825da76410c181273ba90b1 was independently verified via the GitHub API as the v7.0.1 tag commit (not guessed — per repo policy).

Risk is MEDIUM (not LOW) only because the PR modifies a CI workflow and adds validator logic; nothing security-sensitive was found.

Linked issue analysis

Closes #1404 — substantively addressed. All 5 acceptance criteria verified:

  1. Contracts exist for all 8 personas + dev-lead/pr-review/ci-failure-analyst runtimes ✓
  2. Every contract declares triggers.events[], triggers.timers[] (cron + role + justification + stop_condition + event_fast_path), emits[], idempotency_key, concurrency_lane, stop_markers[], budget ✓
  3. Independently cross-checked each contract's triggers against the deployed on: blocks at the PR head SHA via the API: dev-lead.yml (6 events + 3 repository_dispatch types — exact match), dev-lead-retry.yml (cron 15 */2 * * * — match, §6.3 leak correctly declared with null fast path), pr-review-trigger.yml (match, workflow_dispatch deliberately excluded per §3), pr-review-sweep.yml (cron 2,17,32,47 * * * * + workflow_run:[completed] fast path — match), ci-failure-analyst.lock.yml (check_run only — match), persona-mention.yml (issue_comment / pull_request_review_comment / discussion_comment — matches all 8 advisory persona contracts) ✓
  4. Standalone-file location per §8.2 option (b); validate-personas untouched and green ✓
  5. Hermetic validator (no network, yaml.safe_load) + dedicated bats coverage for valid/invalid/missing/malformed ✓

Findings

No blocking issues. Non-blocking notes (carry to a follow-up, ideally before Story 4 / #1406):

  1. Docs/validator emit-vocabulary divergence — the §8.1 normative example in docs/agentic-interaction-model.md uses comment-marker: but the validator's EMIT_PREFIXES only accepts comment: (all authored contracts use comment:). Reconcile the doc example or the validator before #1406 consumes the doc as normative. (Also flagged by codeant-ai/qodo.)
  2. Permissive prefix match — bare commit/push in EMIT_PREFIXES means startswith accepts e.g. commitfoo; tighten when convenient.
  3. Workflow-path check accepts traversal — repo_root / wf with ../ or absolute paths would pass is_file(); low impact (contracts land via reviewed PRs) but an easy hardening.
  4. Pin-version inconsistency — new job uses checkout v7.0.1 while the rest of lint.yml uses v6.0.3; pin is valid, just inconsistent.
  5. Unpinned pip3 install pyyaml matches the existing validate-personas job pattern — consistent with repo precedent, not a regression.

Unresolved review threads are all advisory comments from third-party bots (codeant-ai, gemini-code-assist, qodo); the dev-lead runtime already assessed them (review-changes: no-changes), and no human reviewer has raised questions. The substantive items are captured in the findings above.

MCP secret scan (run_secret_scanning) unavailable in this environment; gitleaks CI check is green.

CI status

All checks green at f5bb8dc: validate-interaction-contracts, bats, shellcheck, actionlint, Lint, unit-tests, CodeQL (actions + python), Agent Security Scan, agent-shield, gitleaks, SonarCloud quality gate, caller-stub-freeze, template-drift, validate-personas, verify-persona-teams/identity, holdout-guard — all SUCCESS. Cancelled entries are superseded duplicate runs.


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 2, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

@don-petry
don-petry enabled auto-merge (squash) August 2, 2026 02:19
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 2, 2026
@don-petry
don-petry disabled auto-merge August 2, 2026 02:19

@don-petry don-petry left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Review — PR #1418 (#1404 interaction contracts)

Genuinely good work, and more thoughtful than the story asked for. Highlights worth naming: splitting runtime (interaction-contracts/*.yml, deployment lens) from role (personas/<id>/interaction.yml) is a distinction §8.1 didn't make but should have; requiring event_fast_path as a key so a null is meaningful (marking the §6.3 leak) is exactly right; binding each contract to a real on-disk workflow keeps it non-aspirational; and the budget == pr-automation-budget ⇒ stop_markers invariant is a nice inference. Validator runs clean — OK: 11 interaction contract(s) valid, invariants hold. — and the 229-line bats suite is real coverage.

One substantive finding.

(should fix) The #860 rule-1 check is bypassed for the one role that actually self-triggers

check_self_trigger is well-built and would fire here. dev-lead subscribes to repository_dispatch:dev-lead-ci-failure, and dev-lead-retry.yml fires exactly that dispatch. Declaring dispatch:dev-lead-ci-failure in emits would trip the collision rule — I confirmed it:

events include repository_dispatch:dev-lead-ci-failure : True
emits declared: ['commit', 'comment:<!-- … budget exhausted -->', 'label:needs-human-review']
→ if 'dispatch:dev-lead-ci-failure' were declared, check_self_trigger would FAIL

interaction-contracts/dev-lead.yml's header addresses this head-on — the re-dispatch is "the TIMER's stop-condition-gated mechanism … NOT a free emit; modeling it as the timer is what keeps the #860 rule-1 self-trigger check meaningful." The reasoning is sound and the gating is real. But the effect is that the check passes vacuously for the only role in the fleet with a live self-trigger loop — the rule is satisfied by a modeling decision rather than by a verified guard.

There's a second instance the check also can't see: emits: commit + a pull_request subscription. dev-lead pushes commits and pull_request:synchronize fires on push — textbook trigger-by-own-output. It's genuinely safe, but only because of the dev-lead-own-commit sender check (scripts/dev-lead-intent.sh:176-185). The docstring honestly flags this class and defers it to Story 4.

So both of dev-lead's real self-trigger paths are currently declared safe by prose in a YAML comment, and nothing mechanical will notice if either guard is later removed — which is precisely the #860 failure shape (a control that is documented rather than enforced).

Suggested shape — turn the exemption into a checkable invariant rather than deleting it:

emits:
  - "dispatch:dev-lead-ci-failure"        # declare it honestly
self_trigger_guards:                       # …and declare why it is safe
  - emit: "dispatch:dev-lead-ci-failure"
    guard: "dev-lead-retry stop_condition (open, not human-gated, budget not exhausted)"
  - emit: "commit"
    guard: "dev-lead-own-commit sender skip — scripts/dev-lead-intent.sh:176-185"

Then check_self_trigger becomes: a collision is allowed only when a matching self_trigger_guards entry exists — and Story 4 (#1406), which already reads real code, can verify each named guard is still present. That keeps the honest modeling, makes the mitigation load-bearing, and means removing a guard breaks CI instead of passing silently.

Happy for this to land as a follow-up rather than blocking #1418 if you'd prefer to keep the story scoped — but it should be a tracked item, not a comment. Say which and I'll file it against the epic.

Minor

  • personas/pr-review/interaction.yml exists but there is no personas/pr-review/persona.yml (pr-review is a runtime, not a persona in personas/). Worth confirming that placement is deliberate and that validate-personas.py won't later trip over a directory with an interaction.yml and no manifest.

Comment thread interaction-contracts/dev-lead.yml
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 2, 2026
@don-petry
don-petry disabled auto-merge August 2, 2026 02:21
coderabbitai[bot]
coderabbitai Bot previously approved these changes Aug 2, 2026
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — fix-reviews (applied)

Changes committed and pushed.

@donpetry-bot
donpetry-bot dismissed coderabbitai[bot]’s stale review August 2, 2026 02:44

Auto-dismissed (#617): coderabbitai[bot] CHANGES_REQUESTED on a superseded commit. The bot re-reviews the new head automatically — a valid concern will return as a fresh review.

@don-petry
don-petry disabled auto-merge August 2, 2026 02:44
@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — waiting on PR blockers (intent: review-changes)

PR: #1418
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-08-02T03:14:59Z

@don-petry

Copy link
Copy Markdown
Collaborator Author

Note

@don-petry I reviewed this PR and no code changes were needed, but it still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews), so I cannot mark it done yet. I'll re-check automatically.
Next attempt after: 2026-08-02T03:14:59Z

@don-petry
don-petry enabled auto-merge (squash) August 2, 2026 02:45
@donpetry-bot

Copy link
Copy Markdown
Contributor

Advisory bots were rate-limited; auto-approval is withheld until they recover. pr-review-sweep will re-review this PR after 2026-08-02T03:47:45Z.

@donpetry-bot donpetry-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Automated review — APPROVED ✓

Risk: MEDIUM
Reviewed commit: 9c4ac5dfd9056730bd0ce638a7c02698e59a2da7
Review mode: triage-approved (single reviewer)

Summary

Re-review after the fix-requested cycle at b37dd82. Three commits since then (+202/−13 across 6 files) resolve the single blocking finding and all carried non-blocking notes. The blocking (should fix) thread from @don-petry on interaction-contracts/dev-lead.yml (the vacuous #860 rule-1 check) is implemented exactly as proposed: dev-lead now honestly declares its retry dispatches (dispatch:dev-lead-ci-failure, -reviews-retry, -issue-retry) and the commit emit collision, each legalized only by a matching self_trigger_guards: entry naming the in-code guard and its location — giving #1406 a verifiable hook. The validator enforces guard shape (emit must be declared in emits, non-empty guard + location) and only suppresses a collision when a matching guard exists. All 16 review threads are now resolved.

Linked issue analysis

Closes #1404 — substantive AC verification from prior cycles still holds (contracts for all 8 personas + 3 runtimes; required trigger/timer/emit/idempotency/concurrency/stop-marker/budget fields; triggers cross-checked against deployed on: blocks; hermetic validator + bats coverage). The delta strengthens AC #3 (contracts no longer aspirational — dev-lead's real self-trigger loop is declared, not omitted) and AC #5 (validator now covers guard semantics with 5 new bats cases: guarded self-dispatch allowed, mismatched guard rejected, missing location rejected, undeclared-emit guard rejected, whitespace-only payload rejected).

Findings

Prior blocking finding — resolved. self_trigger_guards: implemented in both interaction-contracts/dev-lead.yml and personas/dev-lead/interaction.yml (commit guard at scripts/dev-lead-intent.sh:176-185); validator's check_self_trigger now fails an unguarded collision and directs authors to declare a guard. Thread resolved by the reviewer.

Prior non-blocking findings — resolved. pip3 install now pinned (pyyaml==6.0.3, --only-binary); persist-credentials: false added to the new lint job's checkout. Also fixed from other reviewers: pr-review.yml declares the sweep re-dispatch (workflow_dispatch:pr-review-trigger, with the new workflow_dispatch: emit prefix); whitespace-only emit payloads rejected via .strip().

New issues: none found. The guard-check logic is sound (guard entries must reference declared emits; prefix-overlap ordering comment-marker: before comment: preserved; the .strip() payload check subsumes the old bare-prefix check). Remaining nit (checkout pinned at v7.0.1 while other jobs in lint.yml use v6.0.3) is cosmetic and consistent with prior-cycle precedent — non-blocking.

MCP secret scan (run_secret_scanning) unavailable in this environment; gitleaks CI check is green at head.

CI status

All checks green at 9c4ac5dfd9056730bd0ce638a7c02698e59a2da7: bats (incl. 5 new guard tests), unit-tests, validate-interaction-contracts, validate-personas, shellcheck/ShellCheck, Lint, actionlint, CodeQL (actions + python), Agent Security Scan, agent-shield, SonarCloud quality gate, gitleaks, caller-stub-freeze, template-drift, gh-aw-compile, verify-persona-teams/identity, holdout-guard, CodeRabbit, Graphite — SUCCESS. CANCELLED entries are superseded duplicate runs from earlier pushes; SKIPPED entries are conditional dependency-audit ecosystems. Branch is BEHIND main but MERGEABLE.


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

@don-petry
don-petry disabled auto-merge August 2, 2026 02:49
@sonarqubecloud

sonarqubecloud Bot commented Aug 2, 2026

Copy link
Copy Markdown

@don-petry

Copy link
Copy Markdown
Collaborator Author

Dev-Lead — waiting on PR blockers (intent: review-changes)

PR: #1418
No changes were committed, but the PR still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews). The retry cron will re-attempt automatically. Next attempt after: 2026-08-02T03:20:25Z

@don-petry

Copy link
Copy Markdown
Collaborator Author

Note

@don-petry I reviewed this PR and no code changes were needed, but it still has blocking checks or reviews (failing or cancelled checks, or changes-requested reviews), so I cannot mark it done yet. I'll re-check automatically.
Next attempt after: 2026-08-02T03:20:25Z

@don-petry
don-petry merged commit 792817d into main Aug 2, 2026
63 of 75 checks passed
@don-petry
don-petry deleted the dev-lead/issue-1404-20260802-0151 branch August 2, 2026 02:50

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_validate_interaction_contracts.bats`:
- Around line 381-386: Update the test “validate-interaction-contracts rejects
an emit with a whitespace-only payload” to assert the specific
whitespace-payload diagnostic, such as “non-empty value,” instead of the generic
“emits” substring; keep the nonzero status assertion unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e783b3f4-1ed4-4c1a-81d3-093e5186ab27

📥 Commits

Reviewing files that changed from the base of the PR and between 0d62c2e and f9135ed.

📒 Files selected for processing (5)
  • .github/workflows/lint.yml
  • interaction-contracts/pr-review.yml
  • interaction-contracts/validate-interaction-contracts.py
  • personas/dev-lead/interaction.yml
  • tests/test_validate_interaction_contracts.bats

Comment on lines +381 to +386
@test "validate-interaction-contracts rejects an emit with a whitespace-only payload (label: )" {
sed -i 's# - "label:demo"# - "label: "#' "$TMP/personas/demo/interaction.yml"
run python3 "$VALIDATOR" "$TMP"
[ "$status" -ne 0 ]
[[ "$output" == *"emits"* ]]
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the whitespace-payload assertion specific.

[[ "$output" == *"emits"* ]] can pass when another validation rule causes the failure. Match the whitespace-payload diagnostic, such as non-empty value.

Proposed assertion
-  [[ "$output" == *"emits"* ]]
+  [[ "$output" == *"non-empty value"* ]]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@test "validate-interaction-contracts rejects an emit with a whitespace-only payload (label: )" {
sed -i 's# - "label:demo"# - "label: "#' "$TMP/personas/demo/interaction.yml"
run python3 "$VALIDATOR" "$TMP"
[ "$status" -ne 0 ]
[[ "$output" == *"emits"* ]]
}
`@test` "validate-interaction-contracts rejects an emit with a whitespace-only payload (label: )" {
sed -i 's# - "label:demo"# - "label: "#' "$TMP/personas/demo/interaction.yml"
run python3 "$VALIDATOR" "$TMP"
[ "$status" -ne 0 ]
[[ "$output" == *"non-empty value"* ]]
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_validate_interaction_contracts.bats` around lines 381 - 386,
Update the test “validate-interaction-contracts rejects an emit with a
whitespace-only payload” to assert the specific whitespace-payload diagnostic,
such as “non-empty value,” instead of the generic “emits” substring; keep the
nonzero status assertion unchanged.

@donpetry-bot

Copy link
Copy Markdown
Contributor

Review — fix requested (cycle 1/3)

The automated review identified the following issues. Please address each one:

Findings to fix

Automated review — NEEDS HUMAN REVIEW

Risk: MEDIUM
Reviewed commit: f9135edc7e4b165920f4698a22995906d79ee0ba
Review mode: triage-approved (single reviewer)

Summary

Adds machine-readable interaction contracts for all agentic roles plus a hermetic Python validator wired into CI with bats coverage (1103 additions, 14 files). Code quality is high and the human reviewer's substantive finding (self_trigger_guards as a checkable invariant) was fully implemented. Escalating only because an active CHANGES_REQUESTED review from CodeRabbit with one unresolved minor thread blocks approval.

Linked issue analysis

Closes #1404 (Phase 2: machine-readable interaction contracts per the §8.1 standard). Substantively addressed: contracts exist for all 8 personas plus 3 runtime lenses, the validator enforces the §8.1 shape, timer invariants, workflow-path existence, and the #860 rule-1 self-trigger check. don-petry's review finding — that self-trigger exemptions were documented in prose rather than enforced — was resolved in code: check_self_trigger now permits a collision only when a matching self_trigger_guards entry names the in-code guard, with bats coverage for guarded/unguarded/malformed cases.

Findings

Blocking (process): CodeRabbit's latest review (2026-08-02T02:53Z) is CHANGES_REQUESTED with 1 unresolved thread on tests/test_validate_interaction_contracts.bats: the whitespace-payload test asserts the broad substring "emits" where the validator emits the specific "non-empty value" diagnostic. Valid minor nit — a one-line fix ([[ "$output" == *"non-empty value"* ]]), then resolve the thread.

Security: None. Validator uses yaml.safe_load, no subprocess/eval/network. New workflow job uses SHA-pinned checkout, persist-credentials: false, version-pinned PyYAML, 5-min timeout. Gitleaks passed on head SHA. MCP secret-scanning tool was not available in this session; the gitleaks CI check covers this PR.

Note: The only change since the prior approved review at 9c4ac5d is a merge of main (unrelated #1414 work) — no new PR content.

CI status

All checks green on head SHA f9135edc7e4b165920f4698a22995906d79ee0ba: 55 successful including Lint, ShellCheck, gitleaks, CodeQL (actions + python), unit-tests, bats, actionlint, validate-interaction-contracts, agent-shield, SonarCloud. Cancelled entries are superseded runs from earlier commits; the single pending check is this review run itself.


Reviewed automatically by the PR-review agent (single-reviewer mode: fable 5). Reply if you need a human review.

Additional tasks

  1. Resolve all unresolved review thread comments from other reviewers
  2. Ensure all CI checks pass after your changes
  3. Rebase on the target branch if behind
  4. Do NOT modify files unrelated to the findings above

The review cascade will automatically re-review after new commits are pushed.

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

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Phase 2] Author a machine-readable interaction contract for every agentic role, per the standard

2 participants