Skip to content

fix(pull-requests): decode native Gitea reactions - #32

Merged
kalvenschraut merged 6 commits into
gitea/warning-checksfrom
gitea/reaction-content
Sep 8, 2026
Merged

kalvenschraut merged 6 commits into
gitea/warning-checksfrom
gitea/reaction-content

Conversation

@kalvenschraut

@kalvenschraut kalvenschraut commented Sep 5, 2026 •

Copy link
Copy Markdown
Member

Native Gitea reaction list rows use content, but the adapter decoded an optional reaction property. A successful reaction appeared optimistically and then vanished on refresh because every real row was silently discarded.

Decode Gitea's required content field and group reactions from it. Normalize the native null response for an empty reaction collection without dropping reactions fetched for other conversation subjects. The focused regressions use the native response shape, including user, content, and created_at, and verify viewer attribution and mixed empty/populated subjects through the API path.

Validation: 65 focused Gitea conversation and API tests passed. Targeted lint passed for all changed files. An integrated browser test against the native Gitea fixture confirmed reactions remained visible after a server restart and full-page reload, and that a native null empty description list did not hide a populated issue-comment reaction.

Implementation: Codex (GPT-6).

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai review

Please verify the native Gitea reaction response field against the adapter decoder, viewer attribution, pagination behavior, and regression coverage. This PR is stacked after #23 in stack pingdotgg#6.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Pull request metadata ==='
gh pr view 32 --repo RTVision/t3code --json number,title,baseRefName,headRefName,body,files,commits

echo '=== Diff relative to PR base ==='
git diff --stat origin/"$(gh pr view 32 --repo RTVision/t3code --json baseRefName --jq .baseRefName)"...HEAD
git diff --find-renames --unified=80 origin/"$(gh pr view 32 --repo RTVision/t3code --json baseRefName --jq .baseRefName)"...HEAD -- .

echo '=== Candidate files ==='
fd -t f . | rg -i '(gitea|reaction|conversation|pull.request|comment|api)'

echo '=== Structural outlines ==='
fd -t f -e ts -e tsx . | rg -i '(gitea|reaction|conversation|pull.request|comment|api)' | while IFS= read -r file; do
  echo "--- $file"
  ast-grep outline "$file" --items all || true
done

Length of output: 3022


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Pull request patch from GitHub ==='
gh pr diff 32 --repo RTVision/t3code --patch

echo '=== Structural outlines of changed files ==='
for file in \
  apps/server/src/pullRequest/GiteaConversation.ts \
  apps/server/src/pullRequest/GiteaConversation.test.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts
do
  echo "--- $file"
  ast-grep outline "$file" --items all
done

echo '=== Decoder and reaction call-path references ==='
rg -n -C 5 --type ts \
  '(content|reaction|created_at|viewer|currentUser|paginate|pagination|list.*reaction|reactions)' \
  apps/server/src/pullRequest/GiteaConversation.ts \
  apps/server/src/pullRequest/GiteaConversation.test.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

Length of output: 86751


🤖 web_search executed:

Gitea API v1 list issue reactions response schema Reaction content user created_at OpenAPI

Length of output: 13906


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Conversation-reaction implementation locations ==='
rg -n -C 8 --type ts \
  '(listConversationReactions|RawGiteaReaction|reactionsForViewer|paginate|paginated|x-total-count|link)' \
  apps/server/src/pullRequest/GiteaPullRequestApi.ts

echo '=== Conversation-reaction implementation ==='
implementation_line=$(rg -n --type ts 'listConversationReactions' apps/server/src/pullRequest/GiteaPullRequestApi.ts | head -1 | cut -d: -f1)
sed -n "$((implementation_line - 25)),$((implementation_line + 150))p" apps/server/src/pullRequest/GiteaPullRequestApi.ts

echo '=== Focused API regression tests ==='
sed -n '1540,1620p' apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

echo '=== Focused conversation tests ==='
sed -n '1,90p' apps/server/src/pullRequest/GiteaConversation.test.ts

echo '=== All raw-reaction schema references ==='
rg -n -C 3 --type ts '\bRawGiteaReaction\b' apps/server/src

Length of output: 23851


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Generic paginated-slice helper ==='
helper_line=$(rg -n --type ts 'const readUnknownSlice|function readUnknownSlice' apps/server/src/pullRequest/GiteaPullRequestApi.ts | head -1 | cut -d: -f1)
sed -n "$((helper_line - 15)),$((helper_line + 130))p" apps/server/src/pullRequest/GiteaPullRequestApi.ts

echo '=== Conversation reaction loader ==='
sed -n '1635,1725p' apps/server/src/pullRequest/GiteaPullRequestApi.ts

echo '=== Test runner metadata (not executed) ==='
fd -t f '^package\.json$' . -x sh -c '
  case "$1" in
    ./package.json|./apps/server/package.json)
      echo "--- $1"
      jq "{name, scripts}" "$1"
      ;;
  esac
' sh {}

echo '=== Test configuration files ==='
fd -t f -e ts -e js -e json . | rg '(^|/)(vitest|vite)\.config\.[^.]+$|package\.json$' | head -50

Length of output: 13522


@kalvenschraut Reviewed PR #32 with the stack context considered.

No findings.

  • Gitea documents content, created_at, and user for native issue reaction rows. The decoder now requires content. This matches the native API schema. Gitea API documentation
  • reactionsForViewer maps row.content. It trims actor logins. It compares the viewer login without case sensitivity.
  • listConversationReactions decodes each row through RawGiteaReaction before it calls reactionsForViewer.
  • The API regression covers pull-request reactions, issue-comment reactions, and viewer attribution through the API path.
  • The pagination regression verifies that x-total-count requests page 2 and preserves reactions from both native content rows.

I could not execute the focused tests in this inspection environment. The static review found the implementation and regression coverage consistent with the stated validation.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 58 minutes.

Check out review usage here.

View limit details

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

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 434e8a24-2b53-4c6e-b5c4-6c06a5319d4d

📥 Commits

Reviewing files that changed from the base of the PR and between c4fed16 and 09848f4.

📒 Files selected for processing (1)
  • apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 7ef016a4-acf5-489f-99cd-e371bb0cb84d

📥 Commits

Reviewing files that changed from the base of the PR and between 93580c0 and c4fed16.

📒 Files selected for processing (3)
  • apps/server/src/pullRequest/GiteaConversation.test.ts
  • apps/server/src/pullRequest/GiteaConversation.ts
  • apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

Gitea reaction decoding now requires the native content field. Reaction grouping reads this field, and tests cover native response decoding, viewer detection, actor exclusion, timestamps, and pagination fixtures.

Changes

Gitea reaction handling

Layer / File(s) Summary
Update reaction parsing
apps/server/src/pullRequest/GiteaConversation.ts
RawGiteaReaction now requires content. Reaction grouping maps row.content through the provider content map.
Validate native reaction responses
apps/server/src/pullRequest/GiteaConversation.test.ts, apps/server/src/pullRequest/GiteaPullRequestApi.test.ts
Tests decode native Gitea reactions and validate grouping, viewer detection, actor exclusion, timestamps, and paginated fixtures.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to c4fed

Gitea reactions now decode and group from the native content field, preserving reactions after refresh while retaining viewer attribution and pagination behavior. The change is ready to merge.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 3 files.
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.
Title check ✅ Passed The title clearly and concisely describes the main change: decoding native Gitea reactions.
Description check ✅ Passed The description explains what changed, why it was needed, implementation details, regression coverage, and validation results. It does not include the template checklist, but the required change ratio…
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gitea/reaction-content

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.

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai review

Please review the latest commit 5a889ffeb, especially the reaction-only nullAsEmpty scope and the regression proving one native null subject does not discard another subject's populated reaction list.

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '=== Commit metadata and patch ==='
git show --no-ext-diff --format=fuller --find-renames --unified=100 5a889ffeb -- .

echo '=== Changed files ==='
git diff-tree --no-commit-id --name-only -r 5a889ffeb

echo '=== Candidate decoder/API/test outlines ==='
for file in $(git diff-tree --no-commit-id --name-only -r 5a889ffeb -- | rg '\.(ts|tsx)$'); do
  echo "--- $file"
  ast-grep outline "$file" --items all || true
done

echo '=== nullAsEmpty references and decoder call paths ==='
rg -n -C 8 --type ts '\bnullAsEmpty\b|\bRawGiteaReaction\b|\blistConversationReactions\b|\breactionsForViewer\b' apps/server/src

Length of output: 68388


@kalvenschraut Reviewed commit 5a889ffeb.

No findings.

  • nullAsEmpty is opt-in in readUnknownPage and readUnknownSlice.
  • listConversationReactions is the caller that enables nullAsEmpty: true.
  • Other list operations continue to require an array response.
  • A native null reaction response becomes an empty reaction list for only that target.
  • The new regression returns null for the pull-request reaction target and a populated native reaction row for issue:12.
  • The test verifies that pullRequest is empty and that bySubjectId.get("issue:12") still contains the heart reaction.

I did not run the test suite in this inspection environment. The static implementation and regression test match the requested behavior.

You are interacting with an AI system.

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai configuration

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown

Configuration used: Path: .coderabbit.yaml

CodeRabbit configuration
# Source: defaults
language: en-US
# Source: defaults
tone_instructions: ''
# Source: defaults
early_access: false
# Source: defaults
enable_free_tier: true
# Source: defaults
inheritance: false
reviews:
  # Source: defaults
  profile: chill
  # Source: defaults
  request_changes_workflow: false
  # Source: defaults
  high_level_summary: true
  # Source: defaults
  high_level_summary_instructions: ''
  # Source: defaults
  high_level_summary_placeholder: '`@coderabbitai` summary'
  # Source: defaults
  high_level_summary_in_walkthrough: false
  # Source: defaults
  auto_title_placeholder: '`@coderabbitai`'
  # Source: defaults
  auto_title_instructions: ''
  # Source: Repository YAML (base)
  review_status: false
  # Source: defaults
  review_details: false
  # Source: defaults
  review_progress: true
  # Source: defaults
  commit_status: true
  # Source: defaults
  fail_commit_status: false
  # Source: defaults
  collapse_walkthrough: true
  # Source: defaults
  changed_files_summary: true
  # Source: defaults
  sequence_diagrams: true
  # Source: defaults
  estimate_code_review_effort: true
  # Source: defaults
  assess_linked_issues: true
  # Source: defaults
  related_issues: true
  # Source: defaults
  related_prs: true
  # Source: defaults
  suggested_labels: true
  # Source: defaults
  labeling_instructions: []
  # Source: defaults
  mutually_exclusive_groups: {}
  # Source: defaults
  auto_apply_labels: false
  # Source: defaults
  suggested_reviewers: true
  # Source: defaults
  auto_assign_reviewers: false
  # Source: defaults
  suggested_reviewers_instructions: []
  # Source: defaults
  in_progress_fortune: true
  # Source: defaults
  poem: false
  # Source: defaults
  enable_prompt_for_ai_agents: true
  # Source: defaults
  path_filters: []
  # Source: defaults
  path_instructions: []
  # Source: defaults
  abort_on_close: true
  # Source: defaults
  disable_cache: false
  slop_detection:
    # Source: defaults
    enabled: true
    # Source: defaults
    include_all_authors: false
  auto_review:
    # Source: Repository YAML (base)
    enabled: false
    # Source: defaults
    description_keyword: ''
    # Source: defaults
    auto_incremental_review: true
    # Source: defaults
    auto_pause_after_reviewed_commits: 5
    # Source: defaults
    ignore_title_keywords: []
    # Source: defaults
    labels: []
    # Source: defaults
    drafts: false
    # Source: defaults
    base_branches: []
    # Source: defaults
    ignore_usernames: []
  finishing_touches:
    docstrings:
      # Source: defaults
      enabled: true
    unit_tests:
      # Source: defaults
      enabled: true
    simplify:
      # Source: defaults
      enabled: false
    autofix:
      # Source: defaults
      enabled: true
    fix_ci:
      # Source: defaults
      enabled: true
    resolve_merge_conflict:
      # Source: defaults
      enabled: true
    # Source: defaults
    custom: []
  pre_merge_checks:
    # Source: defaults
    override_requested_reviewers_only: false
    docstrings:
      # Source: defaults
      mode: warning
      # Source: defaults
      threshold: 80
    title:
      # Source: defaults
      mode: warning
      # Source: defaults
      requirements: ''
    description:
      # Source: defaults
      mode: warning
    issue_assessment:
      # Source: defaults
      mode: warning
    # Source: defaults
    custom_checks: []
  # Source: defaults
  post_merge_actions: []
  tools:
    ast-grep:
      # Source: defaults
      rule_dirs: []
      # Source: defaults
      util_dirs: []
      # Source: defaults
      essential_rules: true
      # Source: defaults
      packages: []
    shellcheck:
      # Source: defaults
      enabled: true
    ruff:
      # Source: defaults
      enabled: true
    markdownlint:
      # Source: defaults
      enabled: true
    github-checks:
      # Source: defaults
      enabled: true
    languagetool:
      # Source: defaults
      enabled: true
      # Source: defaults
      enabled_rules: []
      # Source: defaults
      disabled_rules: []
      # Source: defaults
      enabled_categories: []
      # Source: defaults
      disabled_categories: []
      # Source: defaults
      enabled_only: false
      # Source: defaults
      level: default
    biome:
      # Source: defaults
      enabled: true
    hadolint:
      # Source: defaults
      enabled: true
    swiftlint:
      # Source: defaults
      enabled: true
    phpstan:
      # Source: defaults
      enabled: true
      # Source: defaults
      level: default
    phpmd:
      # Source: defaults
      enabled: true
    phpcs:
      # Source: defaults
      enabled: true
    golangci-lint:
      # Source: defaults
      enabled: true
    yamllint:
      # Source: defaults
      enabled: true
    gitleaks:
      # Source: defaults
      enabled: true
    trufflehog:
      # Source: defaults
      enabled: true
    checkov:
      # Source: defaults
      enabled: true
    tflint:
      # Source: defaults
      enabled: true
    detekt:
      # Source: defaults
      enabled: true
    eslint:
      # Source: defaults
      enabled: true
      e18e:
        # Source: defaults
        enabled: true
    flake8:
      # Source: defaults
      enabled: true
    fbinfer:
      # Source: defaults
      enabled: true
      # Source: defaults
      enable_java: false
    fortitudeLint:
      # Source: defaults
      enabled: true
    rubocop:
      # Source: defaults
      enabled: true
    buf:
      # Source: defaults
      enabled: true
    regal:
      # Source: defaults
      enabled: true
    actionlint:
      # Source: defaults
      enabled: true
    zizmor:
      # Source: defaults
      enabled: true
    pmd:
      # Source: defaults
      enabled: true
    clang:
      # Source: defaults
      enabled: true
    cppcheck:
      # Source: defaults
      enabled: true
    vale:
      # Source: defaults
      enabled: true
    verilator:
      # Source: defaults
      enabled: true
    opengrep:
      # Source: defaults
      enabled: true
    semgrep:
      # Source: defaults
      enabled: true
    circleci:
      # Source: defaults
      enabled: true
    clippy:
      # Source: defaults
      enabled: true
    sqlfluff:
      # Source: defaults
      enabled: true
    squawk:
      # Source: defaults
      enabled: true
    trivy:
      # Source: defaults
      enabled: true
    prismaLint:
      # Source: defaults
      enabled: true
    pylint:
      # Source: defaults
      enabled: true
    oxc:
      # Source: defaults
      enabled: true
    shopifyThemeCheck:
      # Source: defaults
      enabled: true
    luacheck:
      # Source: defaults
      enabled: true
    brakeman:
      # Source: defaults
      enabled: true
    dotenvLint:
      # Source: defaults
      enabled: true
    htmlhint:
      # Source: defaults
      enabled: true
    stylelint:
      # Source: defaults
      enabled: true
    checkmake:
      # Source: defaults
      enabled: true
    osvScanner:
      # Source: defaults
      enabled: true
    oasdiff:
      # Source: defaults
      enabled: true
    reactDoctor:
      # Source: defaults
      enabled: true
    presidio:
      # Source: defaults
      enabled: true
    blinter:
      # Source: defaults
      enabled: true
    smartyLint:
      # Source: defaults
      enabled: true
    emberTemplateLint:
      # Source: defaults
      enabled: true
    skillspector:
      # Source: defaults
      enabled: true
    psscriptanalyzer:
      # Source: defaults
      enabled: true
chat:
  # Source: defaults
  art: true
  # Source: defaults
  allow_non_org_members: true
  # Source: defaults
  auto_reply: true
  integrations:
    jira:
      # Source: defaults
      usage: auto
    linear:
      # Source: defaults
      usage: auto
knowledge_base:
  # Source: defaults
  opt_out: false
  web_search:
    # Source: defaults
    enabled: true
  code_guidelines:
    # Source: defaults
    enabled: true
    # Source: defaults
    filePatterns: []
  learnings:
    # Source: defaults
    scope: auto
    # Source: defaults
    approval_delay: 0
  issues:
    # Source: defaults
    scope: auto
  jira:
    # Source: defaults
    usage: auto
    # Source: defaults
    project_keys: []
    # Source: defaults
    excluded_project_keys: []
  linear:
    # Source: defaults
    usage: auto
    # Source: defaults
    team_keys: []
  pull_requests:
    # Source: defaults
    scope: auto
  mcp:
    # Source: defaults
    usage: auto
    # Source: defaults
    disabled_servers: []
  # Source: defaults
  automatic_linking_mode: disabled
  # Source: defaults
  automatic_repository_linking: false
  # Source: defaults
  linked_repositories: []
code_generation:
  docstrings:
    # Source: defaults
    language: en-US
    # Source: defaults
    path_instructions: []
  unit_tests:
    # Source: defaults
    path_instructions: []
issue_enrichment:
  auto_enrich:
    # Source: defaults
    enabled: false
  planning:
    # Source: defaults
    enabled: true
    auto_planning:
      # Source: defaults
      enabled: true
      # Source: defaults
      labels: []
  labeling:
    # Source: defaults
    labeling_instructions: []
    # Source: defaults
    auto_apply_labels: false

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai approve

@coderabbitai

coderabbitai Bot commented Sep 5, 2026

Copy link
Copy Markdown
✅ Action performed

Comments resolved. Approval is disabled; enable reviews.request_changes_workflow to allow explicit top-level @coderabbitai resolve or @coderabbitai approve commands.

@kalvenschraut

kalvenschraut commented Sep 5, 2026 •

Copy link
Copy Markdown
Member Author

This Gitea-stack tip is now integrated into rtvision with Fable's explicit approval. The combined commit restores both missing #8 lifecycle fixes, applies #4's formatting correction, and resolves the dependency-adapter overlap described on #25. Focused tests and scoped checks passed.

The reaction fix itself remains approved. This original branch is unchanged; preserve the lifecycle and integration corrections when preparing the feature for upstream submission.

Integration: a3ad93268, tree 9e13dd0812b8743ef76d4b8adca2f683317fc9e5. All original feature branches are preserved. Implementation/review: Codex (GPT-6); independent approval for the exact commit and rtvision destination: Claude Fable 5.1 through Claude CLI.

@kalvenschraut

Copy link
Copy Markdown
Member Author

Merge verdict: NO-GO (review gates incomplete).

Head: 5a889ffeb11c176e2c2ac3556bb2065336296e40.

  • Codex: NO-GO for merging under the requested two-reviewer gate. Merge readiness and review history were checked; the full dual code review is incomplete, and this comment is not a code approval.
  • Fable 5.1 / Claude CLI: BLOCKED. The requested claude-fable-5-1 review was attempted, but the CLI reached its session limit before returning a completed verdict. Its reported reset is midnight America/Chicago. There is no fresh Fable GO from this pass.
  • CodeRabbit: No formal APPROVED review. The successful CodeRabbit status check does not satisfy the requested approval gate. This branch has not enabled reviews.request_changes_workflow; the existing CodeRabbit replies on this series identify that configuration as preventing formal approvals.
  • GitHub merge state: MERGEABLE / CLEAN against gitea/warning-checks.
  • Checks: the current rollup contains a successful CodeRabbit status only; it contains no build/test check result. No new tests or browser verification are claimed by this audit.

No merge performed. Resume the independent code reviews when Fable is available, obtain the missing/current CodeRabbit approval where applicable, and recheck the exact head and base before merging.

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai approve

The maintainer requests formal approval for the remaining PRs. Please assess the exact current head 5a889ffeb11c176e2c2ac3556bb2065336296e40 and submit APPROVED only if your review has no remaining blockers. If there is a blocker, leave its concrete reason and the fix required instead. A successful status check alone does not meet this merge gate.

If branch configuration prevents formal approval, please state that explicitly. Independent Codex/Fable code verdicts are being refreshed separately; this request does not authorize merging or bypassing their findings.

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

expected_head='5a889ffeb11c176e2c2ac3556bb2065336296e40'

echo '=== Checked-out HEAD ==='
git rev-parse HEAD
git status --short

echo '=== Requested commit metadata and parent ==='
git show -s --format='commit=%H%nparents=%P%nsubject=%s%n' "$expected_head"

echo '=== Pull request metadata ==='
gh pr view 32 --repo RTVision/t3code \
  --json number,state,headRefName,headRefOid,baseRefName,mergeable,reviewDecision,files \
  --jq '{number,state,headRefName,headRefOid,baseRefName,mergeable,reviewDecision,files: [.files[].path]}'

echo '=== Commit patch ==='
git show --no-ext-diff --find-renames --unified=80 "$expected_head" -- \
  apps/server/src/pullRequest/GiteaConversation.ts \
  apps/server/src/pullRequest/GiteaConversation.test.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

echo '=== Relevant implementation and test references ==='
rg -n -C 6 --type ts \
  '\bnullAsEmpty\b|\bRawGiteaReaction\b|\breactionsForViewer\b|\blistConversationReactions\b|x-total-count|created_at|\bcontent\b' \
  apps/server/src/pullRequest/GiteaConversation.ts \
  apps/server/src/pullRequest/GiteaConversation.test.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

echo '=== Formal-approval configuration ==='
if [ -f .coderabbit.yaml ]; then
  rg -n -C 3 'request_changes_workflow|review_status|auto_review' .coderabbit.yaml
else
  echo '.coderabbit.yaml is absent'
fi

Length of output: 108885


@kalvenschraut I assessed the exact head 5a889ffeb11c176e2c2ac3556bb2065336296e40.

I found no remaining static code blocker.

  • The reaction decoder requires the native Gitea content field.
  • Viewer attribution trims logins and compares them without case sensitivity.
  • Pagination retains reactions from later pages.
  • nullAsEmpty is enabled only for listConversationReactions.
  • The regression verifies that a null pull-request reaction response does not discard the populated issue:12 reaction list.

I cannot submit a formal APPROVED review. The active configuration has reviews.review_status: false and does not enable reviews.request_changes_workflow. Formal approval is disabled for this repository configuration.

You are interacting with an AI system.

@kalvenschraut

Copy link
Copy Markdown
Member Author

Merge verdict: NO-GO. This supersedes the earlier quota-only readiness comment.

Reviewed head: 5a889ffeb11c176e2c2ac3556bb2065336296e40; declared destination: gitea/warning-checks.

  • Codex: GO. Uses native reaction content, preserves viewer attribution/pagination, and limits null-as-empty handling to the reaction read. No blocking defect found in this diff.
  • Fable 5.1 / Claude CLI: GO, completed independent review of 5a889ffeb11c.
  • CodeRabbit: No formal GitHub APPROVED review on this head. Approval was requested. Some bot replies say “Approved” or contain [approve], but the GitHub review records do not contain an approval; this does not pass the requested gate. The original branch configuration does not enable reviews.request_changes_workflow.

Validation: 339 focused integrated PR tests plus 502 cross-provider tests passed at integration head 6114cf39; the integrated server typecheck passed. These checks validate the integrated implementation, not every earlier PR snapshot. The original #12 compiler failure was reproduced separately.

No merge is authorized while any blocker or required approval is outstanding. Recheck the resulting head and current base after corrections or stack merges.

This PR also belongs to the native Gitea stack: merging it would merge lower open members, including blocked #4/#5. Those predecessor gates must pass too.

@kalvenschraut

Copy link
Copy Markdown
Member Author

GO on the individual change — merge blocked by stack

Reviewed commit: 5a889ffeb11c176e2c2ac3556bb2065336296e40.

Codex and Claude Fable 5.1 both approve decoding native Gitea reaction content and limiting null-as-empty handling to reactions. Codex ran the standalone Gitea scope on this exact head: 89 tests across 8 files passed.

GitHub rejects ordinary merging for native-stack members and requires an asynchronous stack merge, which includes preceding PRs. That would include rejected #21, so hold this merge until the prefix is cleared.

Validation by Codex: the exact #36 integration head 6114cf39dac017bd665908effd538e5f4f8d5764 passed 1,002 tests across 39 affected files, scoped server/web/desktop typechecks, and targeted lint (warnings, no errors). These are integration results, not a claim that this standalone head passed those checks. Fable independently reviewed source and diffs via Claude CLI; it did not run the tests.

Reviewers: Codex and Claude Fable 5.1 (Claude CLI).

@kalvenschraut

Copy link
Copy Markdown
Member Author

@coderabbitai review

Please independently review the newly pushed fixes at 09848f4117e92802da6df4698e213e66b1d876b7 and submit a formal GitHub approval on this head only if no blockers remain. Otherwise report the remaining actionable findings. The maintainer requested fresh CodeRabbit approval before merging; an older approval or a green skipped-review status does not satisfy that gate. Codex and Claude Fable 5.1 are separately re-reviewing the changes, including the prior no-go findings in this PR.

@coderabbitai

coderabbitai Bot commented Sep 8, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='RTVision/t3code'
pr='32'
requested='09848f4117e92802da6df4698e213e66b1d876b7'
previous='5a889ffeb11c176e2c2ac3556bb2065336296e40'

echo '=== Exact commit and checked-out state ==='
printf 'HEAD='; git rev-parse HEAD
git status --short
git show -s --format='commit=%H%nparents=%P%nsubject=%s%n' "$requested"
git merge-base --is-ancestor "$previous" "$requested" && echo 'previous_reviewed_commit_is_ancestor=true' || echo 'previous_reviewed_commit_is_ancestor=false'

echo '=== Pull request metadata ==='
gh pr view "$pr" --repo "$repo" \
  --json number,state,headRefName,headRefOid,baseRefName,baseRefOid,mergeable,reviewDecision,files \
  --jq '{number,state,headRefName,headRefOid,baseRefName,baseRefOid,mergeable,reviewDecision,files:[.files[].path]}'

echo '=== Requested commit file list and patch ==='
git diff-tree --no-commit-id --name-status -r "$requested"
git show --no-ext-diff --find-renames --unified=100 "$requested" -- .

echo '=== Pull request delta from merge base ==='
base=$(git merge-base "origin/$(gh pr view "$pr" --repo "$repo" --json baseRefName --jq .baseRefName)" "$requested")
echo "merge_base=$base"
git diff --stat "$base...$requested"
git diff --name-status "$base...$requested"

echo '=== Changed TypeScript outlines ==='
git diff-tree --no-commit-id --name-only -r "$requested" -- | rg '\.(ts|tsx)$' | while IFS= read -r file; do
  echo "--- $file"
  ast-grep outline "$file" --items all || true
done

echo '=== Affected behavior definitions and call sites ==='
rg -n -C 8 --type ts \
  '\b(nullAsEmpty|readUnknownPage|readUnknownSlice|RawGiteaReaction|reactionsForViewer|listConversationReactions|created_at|x-total-count)\b' \
  apps/server/src 2>/dev/null || true

echo '=== Focused test names and native reaction fixtures ==='
rg -n -C 5 --type ts \
  '(Gitea|reaction|content:|reaction:|null|pagination|page=|x-total-count|issue:12)' \
  apps/server/src/pullRequest/GiteaConversation.test.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts 2>/dev/null || true

echo '=== CodeRabbit approval configuration ==='
if [ -f .coderabbit.yaml ]; then
  rg -n -C 3 'request_changes_workflow|review_status|auto_review' .coderabbit.yaml
else
  echo '.coderabbit.yaml is absent'
fi

Length of output: 3606


🏁 Script executed:

#!/bin/bash
set -euo pipefail

repo='RTVision/t3code'
pr='32'
requested='09848f4117e92802da6df4698e213e66b1d876b7'
first_parent='192f07192c59dad9a1ba552c56dce3fb52f7163a'
base='a1b46cd996aa147c02cf3970cf66ec416b20f384'
previous='5a889ffeb11c176e2c2ac3556bb2065336296e40'

echo '=== First-parent delta: newly pushed repair ==='
git diff --stat "$first_parent...$requested"
git diff --name-status "$first_parent...$requested"
git diff --find-renames --unified=120 "$first_parent...$requested" -- .

echo '=== Complete pull-request delta from declared base object ==='
git diff --stat "$base...$requested"
git diff --name-status "$base...$requested"
git diff --find-renames --unified=80 "$base...$requested" -- .

echo '=== Delta since the previously reviewed head ==='
git diff --stat "$previous...$requested"
git diff --name-status "$previous...$requested"
git diff --find-renames --unified=100 "$previous...$requested" -- .

echo '=== Changed-file outlines ==='
git diff --name-only "$base...$requested" -- | while IFS= read -r file; do
  case "$file" in
    *.ts|*.tsx)
      echo "--- $file"
      ast-grep outline "$file" --items all || true
      ;;
  esac
done

echo '=== GiteaPullRequestApi test scope ==='
ast-grep outline apps/server/src/pullRequest/GiteaPullRequestApi.test.ts --items all
rg -n -C 12 --type ts \
  '(describe|it|test)\(|(reaction|content|created_at|null|pagination|page=|x-total-count|issue:12)' \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

echo '=== Reaction API and decoding call path ==='
ast-grep outline apps/server/src/pullRequest/GiteaPullRequestApi.ts --items all
rg -n -C 12 --type ts \
  '\b(readUnknownPage|readUnknownSlice|nullAsEmpty|listConversationReactions|RawGiteaReaction|reactionsForViewer)\b' \
  apps/server/src/pullRequest/GiteaPullRequestApi.ts \
  apps/server/src/pullRequest/GiteaConversation.ts

echo '=== Formal approval configuration and current GitHub reviews ==='
if [ -f .coderabbit.yaml ]; then
  rg -n -C 4 'request_changes_workflow|review_status|auto_review' .coderabbit.yaml
fi
gh api "repos/$repo/pulls/$pr/reviews" --paginate \
  --jq '.[] | {user:.user.login,state,commit_id,submitted_at,body}' || true

Length of output: 127375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

requested='09848f4117e92802da6df4698e213e66b1d876b7'
first_parent='192f07192c59dad9a1ba552c56dce3fb52f7163a'
second_parent='a1b46cd996aa147c02cf3970cf66ec416b20f384'
previous='5a889ffeb11c176e2c2ac3556bb2065336296e40'

echo '=== Commit topology since the prior reviewed commit ==='
git log --oneline --decorate --ancestry-path "$previous..$requested"
echo
echo '=== Merge result relative to each parent ==='
for parent in "$first_parent" "$second_parent"; do
  echo "--- parent=$parent"
  git diff --stat "$parent" "$requested"
  git diff --name-status "$parent" "$requested"
done

echo '=== Merge combined diff and conflict-resolution paths ==='
git show --cc --stat "$requested"
git show --cc --name-only --format='' "$requested"

echo '=== Pull-request comparison paths from GitHub ==='
gh pr diff 32 --repo RTVision/t3code --name-only
gh pr diff 32 --repo RTVision/t3code --patch -- apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

echo '=== Exact reaction regression source ==='
sed -n '1985,2110p' apps/server/src/pullRequest/GiteaPullRequestApi.test.ts
echo '=== Exact reaction implementation source ==='
sed -n '850,890p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '1040,1105p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '1755,1845p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
echo '=== Exact reaction grouping source ==='
sed -n '1,115p' apps/server/src/pullRequest/GiteaConversation.ts

echo '=== Check for unresolved merge markers in merge-result changes ==='
git diff --name-only "$second_parent" "$requested" | while IFS= read -r file; do
  case "$file" in
    *.ts|*.tsx|*.md|*.yaml|*.yml)
      if rg -n '^(<<<<<<<|=======|>>>>>>>)' "$file"; then
        exit 1
      fi
      ;;
  esac
done
echo 'no_merge_markers_found=true'

Length of output: 3437


🏁 Script executed:

#!/bin/bash
set -euo pipefail

requested='09848f4117e92802da6df4698e213e66b1d876b7'
first_parent='192f07192c59dad9a1ba552c56dce3fb52f7163a'
second_parent='a1b46cd996aa147c02cf3970cf66ec416b20f384'

echo '=== Exact merge resolution against first parent ==='
git diff --find-renames --unified=80 "$first_parent" "$requested" -- \
  apps/server/src/pullRequest/GiteaPullRequestProvider.test.ts

echo '=== Exact pull-request change against declared base parent ==='
git diff --find-renames --unified=80 "$second_parent" "$requested" -- \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

echo '=== Repair commit before the merge ==='
git show --no-ext-diff --find-renames --unified=80 192f07192c59dad9a1ba552c56dce3fb52f7163a -- .

echo '=== Provider regression context ==='
rg -n -C 16 --type ts \
  '(Gitea|lifecycle|close|reopen|draft|auto-merge|reaction|pagination|repair)' \
  apps/server/src/pullRequest/GiteaPullRequestProvider.test.ts
echo '=== API reaction regression context ==='
sed -n '1995,2110p' apps/server/src/pullRequest/GiteaPullRequestApi.test.ts

echo '=== API implementation ==='
sed -n '859,882p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '1047,1100p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
sed -n '1761,1838p' apps/server/src/pullRequest/GiteaPullRequestApi.ts
echo '=== Reaction grouping implementation ==='
sed -n '1,105p' apps/server/src/pullRequest/GiteaConversation.ts

echo '=== Conflict marker check in all merge-result changed files ==='
for file in \
  apps/server/src/pullRequest/GiteaPullRequestProvider.test.ts \
  apps/server/src/pullRequest/GiteaPullRequestApi.test.ts
do
  echo "--- $file"
  if rg -n '^(<<<<<<<|=======|>>>>>>>)' "$file"; then
    exit 1
  fi
done
echo 'no_merge_markers_found=true'

Length of output: 45524


@kalvenschraut Reviewed exact head 09848f4117e92802da6df4698e213e66b1d876b7.

No static blockers found.

  • The merge removes the duplicate nullAsEmpty declaration from readUnknownSlice.
  • Only listConversationReactions enables nullAsEmpty.
  • RawGiteaReaction requires native Gitea content.
  • Reaction grouping uses content, trims actor logins, and compares the viewer login without case sensitivity.
  • The regression confirms that a null pull-request reaction response does not discard the populated issue:12 reaction list.
  • The pagination regression retains reactions from page 2.
  • The merged test fixture now includes the required Gitea pull-request fields and cwd.
  • The merge-result changed files contain no conflict markers.

I could not run tests in this inspection environment.

The repository enables reviews.request_changes_workflow. I cannot submit a formal GitHub approval from @coderabbitai review. Submit a separate top-level @coderabbitai approve command to request the formal approval action.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@kalvenschraut

Copy link
Copy Markdown
Member Author

Re-review: GO on reaction decoding; NO-GO for merging now

Reviewed head: 09848f4117e92802da6df4698e213e66b1d876b7. This updates my earlier go/no-go comment for the newly pushed repairs.

Native reaction content and null-as-empty handling remain correct, with the fixes carried in earlier heads. CodeRabbit reports no blocker in the incremental change.

Fable 5.1: GO on the individual change.

The candidate inherits the unresolved #9/#10/#12/#21 behaviors, and its native-stack prefix conflicts at #5. Clear those before merging; incremental approval does not clear the prefix.

Validation by Codex: 308 focused tests across 9 files passed on integration head 73dd9c33ab15db71748beb6f0485ec212e6682f8; scoped server, web, and client-runtime typechecks passed, and targeted lint of 21 changed files passed with warnings. A separate single-worker reproduction exposed the native comment-reaction bug (100 reads and no reactions for a 50-reaction comment). These are integration results, not a claim that every standalone head passed the checks. Fable reviewed source and diffs through Claude CLI; it did not run tests.

The remaining native-stack merges must clear their predecessors and the actual target branch. CodeRabbit’s commit-specific comments are distinguished from formal GitHub review records; rate-limited requests are not approvals.

@kalvenschraut

kalvenschraut commented Sep 8, 2026 •

Copy link
Copy Markdown
Member Author

GO — merged after Codex, Fable 5.1, and CodeRabbit review.

Reviewed head: 63b543d0a6eb70617ea35c8f8204739f53edc5cd. This supersedes my previous decision on the older head.

Native reaction decoding remains intact, and this head carries all repaired Gitea behavior from the stack.

CodeRabbit reviewed every exact head and cleared the combined integration. Its commit-specific approval is recorded in that comment; this is not a claim of a new formal GitHub APPROVED review on each PR. All three reviewers require #26 to land with #27 or later; they merged together in the dependency batch.

Validation by Codex: 490 focused tests across 13 files passed on integration head 2e156ad621fb32b241abd4614a367aea7943d12e, including the previously failing native comment-reaction reproduction. Scoped server, web, and client-runtime typechecks passed; targeted lint of 24 changed files passed with warnings. Checks ran sequentially with one test worker. These validate the integration, not separate test runs on every component head. Fable independently reviewed source and diffs via Claude CLI.

Merged: f787a611cffccbdf0fd5e593bba8f615c607f532 at 2026-09-08T04:42:57Z. This PR merged in the 17-member Gitea batch into rtvision; the six dependency PRs followed as one reviewed batch. Final rtvision commit is 20926b20ed4ea72618f7608f70b1d4cea8e40053; its tree 9a0e0253b515456f6a117be5ebccf2cd8e911b01 exactly matches tested integration head #36.

@kalvenschraut
kalvenschraut merged commit f787a61 into rtvision Sep 8, 2026
1 check passed
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