Skip to content

ci: add QA protocol enforcement checks#92

Open
catchmeifyoucaan wants to merge 7 commits into
mainfrom
ci/qa-protocol-enforcement
Open

ci: add QA protocol enforcement checks#92
catchmeifyoucaan wants to merge 7 commits into
mainfrom
ci/qa-protocol-enforcement

Conversation

@catchmeifyoucaan

@catchmeifyoucaan catchmeifyoucaan commented Jul 16, 2026

Copy link
Copy Markdown

Scope

Add organization QA workflow enforcement to Jarvis CI and pin reusable workflows to immutable revisions.

Invariants

  • Jarvis protocol semantics and public contract remain unchanged.
  • Existing validation checks remain enabled.

Design

Use the centralized Flow Research credential scanner and PR-template linter as reusable workflows.

Duplicate and idempotency review

CI checks are read-only and repeatable. No protocol records or data migrations are introduced.

Privacy and security review

Reusable workflow references are pinned to reviewed commit SHAs. Credential scanning remains enforced.

Verification

  • Parsed modified workflow YAML.
  • Ran protocol wording and SDK-boundary checks.
  • Remote validate and credential-scanner jobs passed.

Summary by CodeRabbit

  • Bug Fixes

    • Improved canonicalization and hashing consistency for protocol values that include non-ASCII characters.
    • Protocol hashes may change for non-ASCII content to reflect the updated canonical form.
  • Chores

    • Expanded pull request validation to also run when a pull request is edited.
    • Added automated credential scanning and pull request linting checks during validation.

…rue)

The Python SDK used ensure_ascii=False in json.dumps during canonicalization,
while the TypeScript SDK uses JSON.stringify which defaults to escaping non-ASCII
characters. This caused cross-SDK hash disagreement for any protocol message
containing non-ASCII Unicode (accents, CJK, emoji, etc.), breaking event hash
chain integrity.

JA-TM-01 in the Jarvis threat model.
Wires two reusable workflows from Flow-Research/.github:
- credential-scanner: flags plaintext credentials in source files
- pr-template-linter: validates PR body has required sections from template
@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d8ae2fc4-be89-4043-969e-e2ee660f5710

📥 Commits

Reviewing files that changed from the base of the PR and between 47f6ce6 and aac5555.

📒 Files selected for processing (1)
  • .github/workflows/validate.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/validate.yml

📝 Walkthrough

Walkthrough

The validation workflow now handles edited pull requests and runs credential scanning and pull request linting. Protocol canonicalization now escapes non-ASCII characters, changing canonical strings and resulting hashes.

Changes

Workflow validation

Layer / File(s) Summary
Validation workflow triggers and jobs
.github/workflows/validate.yml
The workflow includes the edited pull request event and adds pinned reusable workflows for credential scanning and pull request linting, passing the PR body to the lint job.

Protocol canonicalization

Layer / File(s) Summary
ASCII-safe protocol serialization
packages/python/src/jarvis_protocol/__init__.py
canonicalize_protocol_value now serializes JSON with ensure_ascii=True, changing canonical strings and downstream protocol hashes for non-ASCII values.

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

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description has useful context, but it does not follow the required template or include the mandated Summary, Boundary Check, or Validation checklist items. Rewrite it using the repository template with all required headings, boundary check boxes, compatibility/conformance impact, and the full validation checklist.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the CI enforcement changes and is concise, though it omits the protocol-hash helper change.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/qa-protocol-enforcement

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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a8233319b9

ℹ️ About Codex in GitHub

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

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

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

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


def canonicalize_protocol_value(value: Any) -> str:
return json.dumps(_sort_protocol_value(value), separators=(",", ":"), ensure_ascii=False)
return json.dumps(_sort_protocol_value(value), separators=(",", ":"), ensure_ascii=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Keep Unicode canonicalization aligned with TypeScript

For protocol records containing non-ASCII text, this now produces a different canonical string and therefore a different hash_protocol_value than the TypeScript helper: Python emits {"text":"\u00e9"} while JSON.stringify({text:'é'}) emits {"text":"é"}. Since event hashes and evidence hashes are derived from this serialization, mixed Python/TypeScript implementations will fail to verify otherwise valid Unicode records such as worker names, request notes, or review text; keep ensure_ascii=False or change both SDKs together.

Useful? React with 👍 / 👎.

catchmeifyoucaan and others added 4 commits July 18, 2026 08:15
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
The regenerate script uses os.path.join which produces Windows backslashes. CI runs on Linux and expects forward slashes.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>

@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: 2

🤖 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 @.github/workflows/validate.yml:
- Line 5: Update the validate and credential-scan jobs in the workflow to run
only when github.event.action is not edited, while leaving the pr-lint job able
to handle edited pull request events. Preserve execution for push and other
non-PR events where the action is empty.

In `@packages/python/src/jarvis_protocol/__init__.py`:
- Line 1733: Align hash canonicalization between the Python serializer in
hash_protocol_value and the TypeScript serializer in
packages/typescript/src/index.js so identical payloads, including non-ASCII
strings, produce identical digests; either make both serializers use the same
Unicode escaping behavior or explicitly version the hash contract.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a6df7cf4-611d-4ef5-bb54-c4c2affe03da

📥 Commits

Reviewing files that changed from the base of the PR and between e0c4842 and 47f6ce6.

📒 Files selected for processing (2)
  • .github/workflows/validate.yml
  • packages/python/src/jarvis_protocol/__init__.py


on:
pull_request:
types: [opened, synchronize, reopened, edited]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🚀 Performance & Scalability | 🟠 Major | ⚡ Quick win

Skip heavy and unrelated jobs on PR edits.

Including edited in the pull_request trigger means that every time the PR title or body is modified, all jobs in this workflow will rerun. Since only the new pr-lint job actually inspects the PR body, rerunning the extensive validate test suite and credential-scan on simple text edits wastes CI minutes and delays feedback.

Consider skipping the unrelated jobs when the event action is edited.

⚡ Proposed optimization for the jobs

Apply the following condition to the validate job:

   validate:
+    if: github.event.action != 'edited'
     runs-on: ubuntu-latest
     steps:

And apply the same condition to the credential-scan job:

   credential-scan:
     name: Credential Scanner
+    if: github.event.action != 'edited'
     uses: Flow-Research/.github/.github/workflows/credential-scanner.yml@e519272096a29214dc6f4f36f1a7de2fc6fba96a

(Note: For push events or other non-PR events, github.event.action is empty, so != 'edited' correctly evaluates to true and allows the jobs to run).

🤖 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 @.github/workflows/validate.yml at line 5, Update the validate and
credential-scan jobs in the workflow to run only when github.event.action is not
edited, while leaving the pr-lint job able to handle edited pull request events.
Preserve execution for push and other non-PR events where the action is empty.


def canonicalize_protocol_value(value: Any) -> str:
return json.dumps(_sort_protocol_value(value), separators=(",", ":"), ensure_ascii=False)
return json.dumps(_sort_protocol_value(value), separators=(",", ":"), ensure_ascii=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

set -euo pipefail

echo "=== file outline ==="
ast-grep outline packages/python/src/jarvis_protocol/__init__.py --view expanded || true

echo "=== relevant symbols ==="
rg -n "def hash_protocol_value|ensure_ascii|_sort_protocol_value|hash_protocol_value\(" packages/python/src/jarvis_protocol/__init__.py packages/python -S

echo "=== tests mentioning hash_protocol_value or protocol hash ==="
rg -n "hash_protocol_value|protocol hash|ensure_ascii|json.dumps|_sort_protocol_value" packages/python -S

echo "=== file segment around hash_protocol_value ==="
sed -n '1700,1765p' packages/python/src/jarvis_protocol/__init__.py

Repository: Flow-Research/jarvis

Length of output: 11430


🏁 Script executed:

set -euo pipefail

echo "=== hash tests in python ==="
sed -n '730,785p' packages/python/tests/test_helpers.py

echo "=== README contract mentions ==="
sed -n '1,120p' packages/python/README.md

echo "=== cross-SDK / canonicalization search ==="
rg -n "canonicalize_protocol_value|hash_protocol_value|ensure_ascii|sha256|canonical" packages -S

Repository: Flow-Research/jarvis

Length of output: 50378


🏁 Script executed:

set -euo pipefail

sed -n '730,785p' packages/python/tests/test_helpers.py
printf '\n=== README ===\n'
sed -n '1,120p' packages/python/README.md
printf '\n=== repository search ===\n'
rg -n "canonicalize_protocol_value|hash_protocol_value|ensure_ascii|sha256|canonical" packages -S

Repository: Flow-Research/jarvis

Length of output: 50378


🏁 Script executed:

set -euo pipefail

echo "=== TypeScript canonicalizeProtocolValue ==="
sed -n '1370,1415p' packages/typescript/src/index.js

echo "=== Python/TS Unicode serialization probe ==="
python3 - <<'PY'
import json
value = {"text": "café", "emoji": "⚙️"}
print("python:", json.dumps(value, separators=(",", ":"), ensure_ascii=True))
print("python_no_ascii:", json.dumps(value, separators=(",", ":"), ensure_ascii=False))
PY

node - <<'JS'
const value = {text: "café", emoji: "⚙️"};
console.log("node:", JSON.stringify(value));
JS

Repository: Flow-Research/jarvis

Length of output: 1693


Preserve the shared hash canonicalization. packages/python/src/jarvis_protocol/__init__.py:1732-1733 now escapes non-ASCII characters, but packages/typescript/src/index.js still serializes the same values as raw Unicode. That makes hash_protocol_value() produce different digests for the same payload across SDKs whenever strings contain non-ASCII data. Align the canonicalization or version the hash contract.

🤖 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 `@packages/python/src/jarvis_protocol/__init__.py` at line 1733, Align hash
canonicalization between the Python serializer in hash_protocol_value and the
TypeScript serializer in packages/typescript/src/index.js so identical payloads,
including non-ASCII strings, produce identical digests; either make both
serializers use the same Unicode escaping behavior or explicitly version the
hash contract.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant