Skip to content

Add Backport Tool Analysis - #3389

Merged
justsmth merged 7 commits into
aws:mainfrom
tianyiy-tim:add-backport-tool-analysis
Aug 19, 2026
Merged

Add Backport Tool Analysis#3389
justsmth merged 7 commits into
aws:mainfrom
tianyiy-tim:add-backport-tool-analysis

Conversation

@tianyiy-tim

@tianyiy-tim tianyiy-tim commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Issues:

Addresses P425131803

Description of changes:

Currently security fixes (or features) must be manually backported to supported LTS and FIPS branches by manually locating the affected branches from the change in code through either git blame or running tests against each branch. For a single fix this can tedious but still manageable, however when multiple fixes arrive, the coordination overhead complicates this process.

This pull request adds a tool that identifies which currently supported branches are affected by a given commit or collection of commits.

Call-outs:

  • The tool only reports its findings from its analysis of the collection of commits and does not perform any cherrypicks automatically.

  • Anything that git history cannot settle is flagged for AI to review, never immediately flagged as not affected, avoiding false negatives.

  • The model answers through a schema, not prose. It's given one tool, record_verdict, forced with tool_choice, whose input_schema constrains the verdict to yes | no | uncertain and confidence to high | medium | low. Bedrock returns the arguments as a dict already in that shape, so there is no reply text to parse. That removes a whole class of bug rather than guarding it: earlier versions read the verdict out of Markdown, and a reasoning sentence starting with "No" could clear a branch.

    Two Bedrock limits are worth knowing, both confirmed against the live model: "strict": true on a tool is rejected (400 tools.0.custom.strict: Extra inputs are not permitted), and so is output_config with a json_schema (400 output_config.format: Extra inputs are not permitted), which is the response-format style the Bedrock guide shows. So the enums are a strong steer rather than a hard guarantee, and read_verdict still validates: an off-enum value, a missing field, a wrong type, a reply with no record_verdict call, or a reply cut short by the token limit all read as no answer, and no answer leaves the branch flagged.

  • A fix that reaches inside crypto/fipsmodule/ gets a FIPS boundary warning after the table. The module is validated as a build of exactly that source, so a backport there has certification consequences this tool cannot judge; all it can do is make sure nobody finds out later. The file list goes into the saved run so publish (Add backport publish command #3415) can carry the same warning into every pull request it opens. Tests and generated files under that path are excluded, since neither is compiled into the module and a warning that fires on those stops meaning anything.

  • Locally, the AI pass runs on local Amazon Bedrock credentials, can refer to the README.md for setup inquiry and troubleshooting.

  • Currently this is the analyze command only. Applying cherrypicks (Add backport apply command #3414), opening the pull requests (Add backport publish command #3415), CI integration (Run the backport bot in CI #3416) and merge conflict resolution (Add backport resolve command #3417) follow on top of this one, in that order. Each is reviewable on its own diff, and each leaves the tool working.

Testing:

Tested with two layers run from 'util/backport' from an AWS-LC checkout.

Unit tests - 137 cases, no checkout or credentials required:

python3 -m unittest testing.test_engine

They cover the pure helpers (whitespace normalization, C-file detection, comment and boilerplate line filters, source-file selection, test/generated path check, branch ordering), the verdict the model records and every way it can be unreadable, the FIPS boundary check including the paths that must not match it, and the engine itself against a stubbed git: patch-id fingerprinting, cherry-pick trailers, already-patched detection, rename following, every verdict classify_branch can reach, the prompt budget, and the support-window dates.

Replay bench - 39 real AWS-LC fixes across 7 release branches with 157 fix branch cells:

python3 testing/replay_fixes.py --no-ai   # git history only, ~5 min
python3 testing/replay_fixes.py           # with the AI pass, ~20 min

Each fix is replayed in a throwaway sandbox with 'origin/main' pinned to the fix and every branch that received a backport wound back to the commit before it (making the tool unable to see the answer). The sandbox borrows objects from the checkout, so nothing is cloned.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

@codecov-commenter

codecov-commenter commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.44%. Comparing base (8ed4798) to head (184f7fd).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3389      +/-   ##
==========================================
+ Coverage   78.22%   78.44%   +0.21%     
==========================================
  Files         698      698              
  Lines      124580   124582       +2     
  Branches    17286    17291       +5     
==========================================
+ Hits        97456    97724     +268     
+ Misses      26199    25934     -265     
+ Partials      925      924       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

samuel40791765

This comment was marked as resolved.

@samuel40791765

This comment was marked as outdated.

@tianyiy-tim
tianyiy-tim force-pushed the add-backport-tool-analysis branch from e9a2a33 to bde5cca Compare August 4, 2026 20:34
@tianyiy-tim
tianyiy-tim force-pushed the add-backport-tool-analysis branch from bde5cca to 3ffe4aa Compare August 4, 2026 20:42
@tianyiy-tim
tianyiy-tim force-pushed the add-backport-tool-analysis branch from 3ffe4aa to 47c32c1 Compare August 4, 2026 21:31
Works out which supported FIPS release branches still need a fix before it
merges. Git history finds the distinctive lines the fix deletes and checks
whether the commits that wrote them reached each branch, then the AI is asked
only about the branches history cannot settle. No answer means affected, so it
can add review noise but never hide a needed backport

Reports only, nothing is cherry-picked, pushed or committed

Graded by a replay bench over 39 real fixes, each replayed in a sandbox wound
back to just before it landed: no missed backports in either mode, 84%
agreement on git history alone and 98% with the AI pass
Comment thread util/backport/src/engine/prompts.py Outdated
Comment thread util/backport/src/engine/consult_ai.py Outdated
Comment thread util/backport/README.md Outdated
Comment thread util/backport/src/engine/prompts.py
read_answer matched "no" as a substring, so Unknown, Cannot determine, Not
enough information and None each cleared a branch. Only the first word after
the label counts now, and only an exact yes or no

An empty changed file list cleared every branch, because any() over no files
is False. One command reaches it, since git diff-tree prints nothing for a
merge commit and still exits 0. changed_files_with_status now checks the exit
status and refuses an empty result, pointing at the range form instead, and
classify_branch answers unsure rather than not affected

Both are a do not know reported as not affected, which is the one direction
that ships a vulnerability

From the review: tests for classify_branches, which holds the per-branch
verdict, copyright headers, docstrings that say what they return, the
max_tokens and slowness sections trimmed from the README, and
util/backport/.gitignore dropped for the repo-wide one. The single entry that
one did not already cover, .backport-runs/, moves to the root file

Also raises the per-file prompt budget and marks a file that was cut off, so
the model cannot read truncation as absent code, drops the dead cwd and stdin
parameters from run() and git(), and always prints the bench per-branch table
instead of hiding it behind -v

Unit tests go from 46 to 106. The replay bench is unchanged, no missed
backports and 84% agreement on git history alone
samuel40791765
samuel40791765 previously approved these changes Aug 13, 2026
nhatnghiho
nhatnghiho previously approved these changes Aug 13, 2026
support_end_date read a YYYY-MM end date as the first of that month, so
out_of_support dropped the branch from the second onward. VERSIONING.md
publishes a bare month meaning supported through all of it, and five of the
seven branches carry one, so each would have left the report for the last
thirty days of its window. fips-2021-10-20 and fips-2021-10-20-1MU are the
next ones, from 2026-10-02

An early drop is the worst shape this can take. The branch is not flagged and
not cleared either, it is simply absent from the table, so a fix landing in
that window reads as needing no backport at all

YYYY-MM now resolves to the last day of the month, and the published day
itself still counts as supported. The tests only probed November 1 and August
10, which left the whole of October unchecked; they now cover the first,
second, fifteenth and last day of the final month, a short and a leap
February, and the exact-day boundary

Reported by the security review on this pull request
nhatnghiho
nhatnghiho previously approved these changes Aug 14, 2026
prasden
prasden previously approved these changes Aug 14, 2026
nhatnghiho
nhatnghiho previously approved these changes Aug 18, 2026
Comment thread util/backport/src/util/config.py Outdated
Comment thread util/backport/src/engine/consult_ai.py Outdated
Comment thread util/backport/testing/test_engine.py Outdated
Comment thread util/backport/testing/test_engine.py Outdated
Comment thread util/backport/src/commands/analyze.py Outdated
Comment thread util/backport/testing/test_engine.py Outdated
tianyiy-tim and others added 2 commits August 18, 2026 15:10
The model now answers by calling record_verdict, forced with tool_choice,
replacing the Markdown parsing in read_answer. read_verdict still checks the
values, since Bedrock rejects strict and output_config for this model. Anything
it cannot read leaves the branch flagged.

Changes under crypto/fipsmodule are called out for FIPS review in analyze and in
the pull requests publish opens. Tests and generated files are skipped.

Also: utf-8 on save_run, skip notices to stderr, and a warning when the version
manifest cannot be read. Unit tests go from 129 to 141.
Comment thread util/backport/src/engine/consult_ai.py
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.

6 participants