AppApptypeAn application you deploy and use, installed into a system or loaded into an application as a component, rather than a library whose functions you call.See every one →What this type is →independently maintainedindependently maintainedoriginPublished by one person or a small company outside SAP. Says nothing about quality; the readings say that.See every one →

AVE

A SAP GUI version explorer and code reviewer that diffs every object in a transport request and records an approval or decline per changed block, by someone other than its author.

Opens a transport request, task, package, class or function group and shows the versions of everything in it on one screen, compared side by side or inline. The diff leaves out reformatting, case changes, generated *_MPC and *_DPC classes, framework includes and lines that only moved, and pairs class declarations by signature. In review mode each block is approved or declined by someone other than its author, with comments and totals per developer and reviewer, and the review is saved in the table ZAVE_REVIEW; a Moving Violations check shows what a request would overwrite in another development system. A block or a whole object can be sent to an LLM under a review profile read from the frontend. Versions, diffs and saved reviews also show in Eclipse ADT and VS Code through VERTEX, where a block can be approved, declined and commented on as well.

Facts

Last pushLicenceMIT

Where it sits

Lives in
Provides
Code reviewABAPCode reviewcapabilityReading a change before it moves on: which files or objects a change contains, what changed in each since an earlier version, and what a reviewer decided about each part. Comparing two versions of one object is where it starts; the review is the record kept of the decision.

Who is behind it

Yurii SychovYurii SychovPersonMaintains this
In the atlas: maintains 9, contributes to 10
@ysichov
maintainer

What it declares

Every artifact

Type
App
Origin
Independently maintained

As an app

Where it runs
does not say
Distributed through
does not say

Connections2

README

quoted from ysichov/AVE under MIT, read
ysichov/AVE/README.mdOn GitHub

AVE — ABAP Versions Explorer & Code Reviewer

SAP ABAP version explorer and code review tool for SAP GUI.

Tested on dozens of transport requests and on real projects — the largest one so far: 4 developers, several months of work, ~25 000 lines of code, reviewed with AVE from end to end.

Also outside SAP GUI. The version history, the diff between two versions and the saved code review — including approving, declining and commenting on a block — are available in Eclipse ADT and in VS Code through VERTEX · Marketplace.

AVE main window

What AVE gives you

  • A whole transport at once — open a request, task, package, class or function group and review everything in it in one screen, instead of opening object after object in SE80 or Eclipse.
  • Objects that do not exist are red — a request listing something nobody can find shows it before it is released.
  • Any two versions compared — side by side or inline, the full source or only the changed blocks.
  • No noise — reformatting and case, generator timestamps, generated *_MPC / *_DPC classes, SAP framework includes, empty class sections, blank blocks, repeated and Transport-of-Copies versions, and lines that merely moved are all left out. What remains is what a person wrote.
  • Class sections read as they were written — declarations are paired by signature, so a method that only moved is not shown as deleted here and added there.
  • The real author — resolved through Transports of Copies, together with the request and task that actually carry the change.
  • Blame — who wrote each line, and when.
  • Code review with a memory — approve or decline each block (never your own), leave comments and decline notes, see totals per developer and per reviewer, close the session and reopen the review later.
  • Moving Violations — what your request will overwrite, or bring back, in another development system once it is moved there.
  • AI, if you want it — send a block or a whole object to an LLM from inside SAP GUI, or copy out a ready-made prompt.
  • Straight into Eclipse — every object, and every changed block, opens in the ADT editor on its own line; one Recalc afterwards and the review is on the new code.
  • Fast navigation — every method of a class, every object of a package or request, one click away.

Table of Contents

  1. Why AVE
  2. Installation
  3. Selection screen
  4. Versions Explorer
  5. Code Reviewer
  6. AI-assisted review
  7. ZAVE_REVIEW table setup
  8. Also in this repository
  9. Author & links

1. Why AVE

First of all — the Eclipse version is the best.

But I want a very fast interface for some cases:

  • I don't want to see the list of all the same versions because of using TOC (Transport of Copies)
  • I do want to see the real object owner, especially when a Transport of Copies is used
  • fast navigation within Transport Requests / Tasks
  • fast navigation within methods inside a class
  • fast navigation within objects inside a package
  • detecting non-existent objects in Transport Requests / Tasks

And the longer answer to the list above: what the standard tools make you do by hand, and what AVE does instead.

1.1 A change is a transport, not an object

SE80 version management and Eclipse compare one object with one of its versions. A transport request is not one object — it is dozens of programs, classes, methods, function modules, CDS views and table definitions. Reviewing it in the standard tools means opening every object by hand, remembering which ones are already done, and starting over tomorrow.

AVE takes the whole scope as the unit of work: enter a request (or a task, a package, a class, a function group) and you get one list of everything in it, the versions of each part, and the diffs — with the objects that do not exist in the system marked red, so a request listing something nobody can find shows it before the request is released.

1.2 The noise problem

A raw line comparison shows everything that differs, and most of it is not a change anybody made. Reviewers learn to scroll past it, and that is exactly how a real change slips through. AVE removes the noise before it reaches the screen:

IgnoredWhy it is not a change
Indentation and caseThe pretty-printer reformats a whole block nobody touched. One switch, because the comparison folds whitespace and case together.
Generator timestampsThe SEGW header (has been generated on … in client …), the function group regeneration stamp (* regenerated at …) and the table maintenance generator header (generation date:, view maintenance generator version:) are rewritten by every regeneration — in every system independently.
Generated Gateway/SEGW classes*_MPC, *_MPC_EXT, *_DPC are generated from the model. *_DPC_EXT holds hand-written code and stays in the review.
SAP-authored includesFunction group framework includes (version author SAP*) are written by the system, not by a developer.
Empty class sectionsA new class always gets all three section includes; the unused ones contain nothing but their own protected section. header.
New objects that are only commentsA generated stub of comment lines is not something to review.
Blank-only blocksA block whose changed lines are all empty is nothing to look at.
Repeated versionsVersions whose source is identical to the previous one, and the Transport-of-Copies versions that create them.
Lines that only movedA block moved elsewhere in the file is not two changes (a deletion and an insertion).

What is left is what a person wrote.

1.3 Class sections come back in random order

The public, protected and private part of a class is stored as a generated include, and SAP regenerates it with the declarations in an arbitrary order. Compare two versions line by line and you get a method that merely moved reported as deleted in one place and added in another — and, worse, the importing and parameter lines of one method matched against another method's, which reads as if signatures had changed.

AVE pairs declarations by their signature and aligns the parameters inside a matched declaration by name. Moved declarations disappear from the diff; a changed one shows exactly the parameter that changed.

1.4 Who really made the change

With a Transport of Copies in the landscape, the version list names the copy, not the author. AVE resolves a T-copy back to its parent request and looks up the responsible task, so every version shows the developer and the request that actually carries the change.

1.5 The other development system

If your landscape has more than one development system — a main one and a project one, say — the retrofit between them is never quite up to date. A request released from one of them can silently overwrite work done in the other, or bring back lines somebody had already deleted, and nobody sees it because everyone is looking at the changed lines, not at the code around them.

Point AVE at the other system and it compares the reviewed source against what is active there, listing everything that will be overwritten or re-inserted when the request is moved. See Moving Violations.

1.6 A review, not just a view

AVE is also a code review workflow: approve or decline every block (never your own), leave comments and decline notes, see totals per developer and per reviewer, and reopen the review later — it lives in one Z table, saved automatically after each action. An LLM can be plugged in, or the prompt copied out to any chat.


2. Installation

a) abapGit — clone https://github.com/ysichov/AVE into a package. You get the report Z_AVE, the observer report Z_AVE_OBSERVER and all ZCL_AVE_* classes.

b) Standalone report — copy src/z_ave_standalone.prog.abap into one new report; it is a generated single-file merge of the whole tool, nothing else is needed. The observer has its own standalone file, src/z_ave_observer_sa.prog.abap.

Only the Code Reviewer needs one extra object — the table ZAVE_REVIEW, see section 7. Everything else runs as is.


3. Selection screen

The whole selection screen of Z_AVE with contains six blocks: Main features, object type block, Layout/UI preferences, Data filter options, AI API config, Diagnostic/Debug.

3.1 Main features

The first block chooses the mode and the review scope.

image
FieldParameterMeaning
Code ReviewerP_CRReview mode: AVE prepares the diffs of a transport scope and opens the review report.
Versions ExplorerP_VEClassic mode: browse and compare versions of one object.
TRs for Re-ViewS_TASKOne or more requests / tasks — the review scope, and also the object when TR/Task is chosen below.
Include TasksP_ITASKRead the objects of the S-tasks belonging to the entered requests too. A request header only carries what was recorded directly on it, so an unreleased K is usually empty while its tasks hold everything.
Remote system Id version checkP_SYSTMS system id — adds a remote baseline version and switches on the Moving Violations check (5.6).
Who is Blame :)P_BLAMECompute blame — who wrote each line. Costly on long histories, see 4.9.
Comment check (request no.)P_CMTCHKMark changed blocks that name no transport request, and objects whose first block is not the change description — see 5.9. Off by default.
3.2 Object types

Choose one object type, enter its name and press Enter.

image
Radio buttonParameterObject
TR/TaskS_TASKTransport request or task (entered in the block above)
Program/IncludeP_PROGReport, include
ClassP_CLASClass
Function ModuleP_FUNCSingle function module
PackageP_PACKDevelopment package
CDS ViewP_DDLSDDL source
Function GroupP_FUGRWhole function group
Table (TABD)P_TABDDDIC table
Domain (DOMA)P_DOMADDIC domain
Data element (DTEL)P_DTELDDIC data element

Interfaces have their own handler too — they are opened from a transport request or a package, not from the Class field.

3.3 Layout / UI preferences
image
FieldParameterMeaning
Compact/Full TextP_CMPCTOnly the changed fragments, or the full source with the changes highlighted.
2-Pane/Single PaneP_PANEOld and new side by side, or one inline pane.
Side-bar/Top-down layoutP_LAYOUTWhere the parts and versions tables sit relative to the viewer.
Open in SAP GUI, not EclipseP_GUINAVSends every object link to the SAP GUI workbench instead of the Eclipse editor — and, because that navigation comes back, lets AVE recompute the object by itself. See 4.12.
3.4 Data filter options
image
FieldParameterMeaning
From DateP_DATEFRShow versions from this date on; the newest predecessor before the date is kept as a baseline.
For userP_USERThis user's last changed objects are marked green.
Remove the same versionsP_RMDPDrop consecutive versions with identical source.
Don't show TOCsP_NTOCHide transport-of-copies versions.
Ignore SAP generatedP_IGNGENKeeps generated code out of the review: framework includes whose version author is SAP* and the SEGW model classes *_MPC, *_MPC_EXT, *_DPC. Uncheck it to review them as well. *_DPC_EXT holds hand-written code and is always reviewable. See 5.8.
Ignore Case/IndentP_ICASECase- and indentation-insensitive comparison. One checkbox for both: the diff folds by removing all whitespace and upper-casing, so the two cannot be separated.
3.5 AI API config
image
FieldParameterMeaning
LLM ProviderP_PROVDropdown: Anthropic, OpenAI, Gemini, Mistral, Groq, Cerebras, OpenRouter, NVIDIA. The list is hard-coded — there is no customizing table to fill.
API URLP_URLLeave empty to use the provider's own endpoint. Fill it for a company gateway, a proxy, or an Azure/Bedrock-style host.
SSL Id (STRUST)P_SSLIDSSL identity used for the call, ANONYM by default. The provider's certificate must be in STRUST under it.
LLM ModelP_MODELModel id. F4 lists the models the provider itself reports, so a new model is offered the day it is released.
API KeyP_APIKEYAPI key.
Max output tokensP_MAXTOKOutput cap per request (default 20000). With a profile that has a schema, too low a cap truncates the answer mid-JSON and nothing parses.
System prompt file (*.md)P_SYSMDOne .md file used as the system prompt, picked with F4. Leave empty to use a profile below.
Review profiles folderP_PPATHFrontend folder holding the review profiles.
Review profileP_PROFProfile name — see section 6.

Four fields have F4: the model (asks the provider), the system prompt file, the profiles folder (folder browse) and the profile (the *.md files found there). URL, model, key, prompt file, folder and profile are stored in SAP memory ids, so they survive between runs.

No SM59 destination is needed. The call goes out through CL_HTTP_CLIENT=>CREATE_BY_URL with the SSL id above, so the only prerequisite is the provider's certificate in STRUST.

Leaving this block empty is fine — the AI links then produce a ready-made prompt page you can copy manually.

3.6 Diagnostic/Debug
image

Both off by default — everything here is for whoever works on AVE itself or has to explain why a Prepare took as long as it did.

FieldParameterMeaning
Metrics (cost estimate)P_METRICAdds a page estimating what a Prepare of this scope will cost, plus the estimate columns and the by-weight selection in the Prepare picker. Without it nothing is measured and the picker opens straight away.
Debug infoP_DEBUGAdds the Debug button of the version view (diff operations and pairing decisions) and the diagnostics log under the review report.

4. Versions Explorer

4.1 The three panes
  • Parts list — the versionable parts of the object: one row for a program, all sections and methods of a class, all objects of a transport or a package.
  • Versions list — the versions of the selected part: version, date, time, author and author name, real object owner, request, request type, task, request description, and the remote system row when one is configured.
  • HTML viewer — the rendered source or diff. Its top-right corner carries Eclipse and Refresh for the part on display, so both stay reachable when the two grids are hidden by Maximize View (4.12).

By default AVE opens the difference between the latest version (base) and the previous one. The list does not include versions without changes — that is a very comfortable thing.

The main window with the three panes annotated: parts, versions, viewer. image

4.2 Toolbar buttons

Main toolbar

ButtonEffect
RefreshReloads parts and versions.
Show Diff / Show VersDiff of two versions, or the plain source of one version.
2-Pane / InlineSide-by-side or inline rendering.
Compact / FullOnly changes, or the full source with changes highlighted.
Blame / Blame ONWho wrote each line.
Maximize ViewHides both tables and expands the HTML viewer.
EclipseOpens the object in Eclipse (ADT), see 4.12.
Debug ONDiagnostic page: the raw diff operations and the pairing decisions behind them. Appears only with Debug info ticked on the selection screen.
📖Opens this instruction in the browser.

The Code Reviewer has a shorter toolbar of its own — Inline, Compact, Maximize View, Eclipse, Reload and 📖. There is no Save button: everything is written to the database on its own, see 5.7.

Versions grid toolbar

ButtonEffect
Diff prev / Diff anyCompare with the previous version, or with a chosen base version.
Set BaseMarks the selected version as the base. Appears only while Diff any is active.
TOCs on / TOCs offShow or hide transport-of-copies versions.
Dups on / Dups offShow or hide versions whose source is identical.
Case/ind on / offCase- and indentation-insensitive comparison.

The parts grid carries Eclipse and Refresh for the object marked in it, and gets one extra button, Back, as soon as you drill into a class or a function group from a transport/package list — it returns to the outer object list.

📸 SCREENSHOT PLACEHOLDER — TOOLBARS Close-up of the main toolbar and of the version grid toolbar.

image
image
4.3 Program / Include / Function Module

Only one part exists, so no object list is needed — AVE goes straight to the version list and opens the latest diff.

📸 SCREENSHOT PLACEHOLDER — PROGRAM 2-PANE

image

Pressing the 2-Pane toggle switches to inline mode.

Double-click on any version shows the difference between it and the previous one.

With Show Vers a single version is loaded into the SAP ABAP editor instead of the HTML viewer, so you get real syntax highlighting and the editor's own search. If the newer source is longer than 1000 lines, AVE opens the source instead of diffing automatically — the diff is one double-click away. Programs and includes are exempt: they always open as a diff.

4.4 Class

The parts list shows all class includes: the sections (Public, Protected, Private), the local and test includes and one row per method. So you can navigate fast to any part of the class.

Section includes are compared declaration by declaration rather than line by line: SAP regenerates them in an arbitrary order, and a plain line diff would report every moved declaration as a delete plus an insert far away from each other, and match the parameters of one method against another method's. Parameters inside a matched declaration are aligned by name as well.

4.5 Transport Request / Task

Shows all TR/Task objects, marking non-existing objects in red.

  • Double-click on a supported object shows its code and version list.
  • Double-click on a class switches to the class objects view (see 4.4); a function group expands into its includes.
  • The Back button returns from the class object list to the TR/Task object list.

The real object owner is resolved even when the version was recorded under a transport of copies: a T-copy request number is resolved back to its parent K request, and the responsible task is looked up for each version.

A transport request opened: object list with red rows for missing objects.

4.6 Package

Shows all package objects, marking non-existing objects in red; unsupported entries stay visible as rows. Navigation works exactly as for a transport request.

4.7 Function Group, CDS View, DDIC objects
  • Function Group — expands into the main SAPL* include and all L* sub-includes.
  • CDS View (DDLS) — the DDL source is read through the SVRS TLOGO controller and rendered with lightweight syntax highlighting.
  • Table / Domain / Data Element — no line diff: two versions of the definition are compared as a table, one row per field, fixed value or attribute, each marked added, deleted or changed.
4.8 Comparing arbitrary versions

To compare any two versions press the toggle button Diff prev — it switches to Diff any. Then select a version and press Set Base; the base row is coloured green.

After that, double-clicking any other version compares it with the base version.

Pressing Maximize View hides the tables so only the version sources remain.

4.9 Blame

With blame on, AVE replays the diffs across the version range and attributes every added or changed line to the author who last touched it, drawing separators between blame blocks.

Blame is not free: it replays the diffs of the whole reviewed range, so on an object with a long history it is the slowest part of a review.

A diff with blame authors and separators visible.

4.10 Remote system version check

Fill Remote system Id version check with a TMS system name and AVE adds a remote baseline row to the version list, so a local version can be diffed directly against what is active in the other system. In review mode the same setting drives the Moving Violations page.

4.11 Long-running operations

Reading versions of a big transport can take a while. AVE shows a throttled progress indicator with an ETA and, once the operation runs past a threshold, asks whether to continue — so a mistyped package does not lock the session.

4.12 Open in Eclipse (ADT)
image

Reading a diff usually ends with wanting to change the code, and AVE is a viewer. Every object it shows therefore carries a jump into the Eclipse editor:

  • the Eclipse button of the main toolbar and of the parts grid opens the object marked in the list, or — with nothing marked — the one on display;
  • every page of the Version Explorer carries an Eclipse button in its top-right corner, next to a Refresh;
  • in the Code Reviewer, the object list, the report, the metrics and picker pages, the developer/reviewer views and the Moving Violations page carry a small ADT badge next to each object name; the object and class views carry Eclipse and Recalc buttons of their own;
  • every changed block carries its own ADT badge, and that one opens the editor on the first changed line of the block — not at the top of a 900-line method.

The jump is a plain adt://<SID>/sap/bc/adt/… URL handed to the frontend: Eclipse registers that protocol when ADT is installed and opens the object. Nothing is called on the SAP side, so no destination and no ADT session are needed — a workstation without Eclipse simply gets an OS error from the URL.

What each part opens:

PartOpens
Class, class pool, public / protected / private sectionThe class source.
MethodThe class, positioned on that method.
Local definitions / implementations / macros / test classesThe matching tab of the class editor.
InterfaceThe interface source.
Program, includeThe program or the include.
Function moduleThe module inside its function group; a group include, under its group.
Function groupThe group's main program.
CDS DDL sourceThe DDL source.
Data elementIts ADT editor.
Table, structure, view, domain, table type, packageThe editor ADT has for it. AVE does not build these links itself — ADT names those resources differently per release, so the system's own ADT URI mapper is asked for the address.

Not every object has a native ADT editor. Classes, interfaces, programs, includes, function groups and modules, CDS and data elements do; the classic Dictionary objects — a domain, and a table on a release where the Dictionary is not source-based yet — are opened by ADT as an embedded SAP GUI view instead, in an Eclipse tab of their own. The jump works either way; only the editor inside the tab differs.

A block badge adds the line to that URL. AVE numbers lines inside the part, while ADT opens the whole class source, so for a method or a section the line is translated first — by locating the part's opening statement in the class source. If it cannot be located, the line is dropped and the jump lands on the object rather than on a wrong line.

Re-reading the object after the change is the other half of it, and the two modes name it differently because they do different things. In the Explorer Refresh reloads parts, versions and the open diff. In the Code Reviewer Recalc drops the cached diff of that one object, recomputes it and reopens the same view — so a review is never given on a stale diff; the toolbar's Reload next to it only re-reads the saved review state from ZAVE_REVIEW and recomputes nothing.

Or skip Eclipse: tick P_GUINAV (3.3) and every one of those links opens the SAP GUI workbench in this window instead — SE24 on the method, SE38 on the include, SE11 on the table. The labels follow the setting, so a button never says Eclipse while sending you to SE80.

That route has something the Eclipse one cannot have: it comes back. The adt:// URL is handed to the operating system and control returns immediately — AVE never learns what you did over there, which is why Recalc is a button you have to press. SAP GUI navigation is a drill-in: AVE regains control the moment you leave the editor, and recomputes that object right there. So the loop is jump, edit, come back, read the new diff — with nothing to press in between.

The price is that leaving the editor without having changed anything also costs the recompute. That is deliberate: the alternative, comparing the source before and after, could only judge objects whose include is readable, and when it decided there was nothing to do it did so invisibly — which looks exactly like a feature that is broken.


5. Code Reviewer

Choose Code Reviewer, enter one or more requests / tasks in TRs for Re-View and press Enter.

5.1 Object overview

AVE first shows the object overview of the scope: every object of the request with its tasks, authors, dates, request(s) and row status, plus a link to open a per-object TR/task drilldown. Nothing is computed yet — this page is cheap. Every row also carries an ADT badge that opens the object in Eclipse, see 4.12.

TR not saved earlier

image

TR Review from database

image

From here:

ActionMeaning
Prepare Code ReviewOpens the picker: tick the objects to compute, then Prepare Selected.
Open ReviewReplaces the Prepare button once a saved review exists for this request: opens it as it was, without recomputing. A saved review also opens by itself when you enter the request.
Recalc DiffNext to Open Review: the same picker, but for objects that already have data — Recalc Selected recomputes them, Delete and recalc drops the saved data of the ticked objects first.
5.2 Preparing a review

Prepare loads the versions of every object in scope, picks the diff pair, computes the diff, the hunks, the statistics and — if enabled — the blame, and caches all of it.

During a long run the screen is refreshed at most every 10 seconds. Up to 50 objects the full report is redrawn each time; above that a one-line progress page takes its place, because rebuilding the report renders every object collected so far and its cost grows with the square of the object count.

5.3 The report

The report aggregates the whole review:

  • totals per developer — insertions, deletions, modifications, hunks,
  • totals per reviewer — approved and declined,
  • one group per object, and one group per class holding its parts,
  • the approve/decline status of every object,
  • links into an object, a class, one developer's or one reviewer's blocks, and the Moving Violations page,
  • an ADT badge next to every object and class name, opening it in Eclipse (4.12).

Scroll position is remembered, so returning from an object lands where you left the report.

5.4 Reviewing a hunk

Open an object and every changed hunk carries its own action row:

LinkEffect
✓ ApproveApproves the hunk, stamped with your user and the time.
✗ DeclineOpens a note dialog; the note is stored with the decline and shown under the hunk.
UndoRemoves the approval or decline. Shown once the hunk carries one.
Add CommentAdds a message to the hunk's comment thread.
EditEdits your own last comment. Shown once you have written one.
ASK AISends this hunk to the LLM — only when the AI block on the selection screen is filled in, see section 6.
ADTOpens the Eclipse editor on the first changed line of this hunk, see 4.12.

Every hunk carries its state next to those links: ○ open, ○ own block, ✓ approved or ✗ declined, the last two with the reviewer and the time. ✓ Approve All at the end of the object approves the rest of it in one go.

Above the blocks the object has its own bar: Declined only, Comments only to narrow the page, the two AI buttons, and Eclipse / Recalc — the object in the editor, and the recompute that picks up what you changed there.

One rule is enforced everywhere: you cannot approve, decline or undo your own block — AVE knows the author of every hunk from the version data, and Approve all skips your own hunks.

Every action is saved to the database immediately, so a session that ends unexpectedly loses nothing. What another reviewer saved meanwhile is picked up when the review is opened again.

Lines that only moved inside a file are filtered out of the review diff, so a re-indented or relocated block does not show up as a change to approve.

image
5.5 Developer and reviewer views

Clicking a developer in the report opens all their blocks; clicking a reviewer opens everything that reviewer acted on. Both pages have their own filter bar:

  • Declined only / Comments only — narrow the page to what still needs attention,
  • Expand all / Collapse all — fold the object groups (they start collapsed),
  • AI prompt diff / AI prompt full — the prompt of everything visible; with the API configured the first one becomes AI Summary and calls the model.

Each object header carries an ADT badge and each block its own, so a block opens in Eclipse on its first changed line (4.12). The scroll position is kept across a drilldown: going into an object and back lands where you left the list.

Opening an object or a class from a developer page keeps that developer: the object shows their blocks only, and a <USER> only / All authors button widens it back. Reading one person's work does not mean reading everyone else's changes in the same method. Approve All is hidden while the page is narrowed — it would approve blocks you cannot see. A reviewer page sets no such filter: the blocks it lists are the ones that reviewer acted on, whoever wrote them.

5.6 Moving Violations

This page matters as soon as there is more than one development system — a main development system plus a separate project one, for example. Both change the same objects, and the retrofit between them, manual or automatic, rarely keeps up. So a request released from the project system can silently carry an old state of an object into the main system and overwrite work that was done there in the meantime, or bring back lines somebody else had already deleted. The changed lines of the request are reviewed carefully; the damage comes from everything around them, which nobody looks at.

Selecting a remote system does not change the review by one character. The blocks, their numbering, their authors and the diff you approve are the same with or without it. What the remote system adds is this page.

The comparison behind it does reach further back, and only it: a request is rarely alone, and if you pick the last of a series that still has to move, the ones before it are not in the other system either — left out, every line of theirs comes back as a divergence of your request. So the subtraction starts from the newest local version whose request that other system already has, read from its own version directory, object by object. If nothing of ours is found there (the object never arrived, or it was retrofitted by hand under their numbers), the ordinary baseline is used.

With a system id in Remote system Id version check, AVE diffs the reviewed source against the source active in that other system and lists only the differences that are not part of the reviewed request:

WarningWhat it means
will be overwritten (deleted)The other system has lines your source does not — moving the request deletes them there.
deleted will be insertedYour source has lines the other system does not — moving the request brings them back there.
divergesBoth, in one block: the code differs and will be overwritten and re-inserted.

Comments count as much as code here. Only a blank line is ignored. The change history of the other system lives in comments — a line of theirs like * 10.08.2026 |CT770018 |ER4K9A16AT| INC3823847 … is the record of a change made over there, and moving the request deletes it. Left out of the comparison, the reviewer saw the code about to be overwritten but not the entry saying who wrote it and why. Our own notes cost nothing: the request adds them, so they appear in its own diff too and cancel out.

Each entry names the object, shows the block with a few lines of context, and states the target system. The page is read-only and carries no approve/decline — these are not somebody's changes to judge, they are a warning that a retrofit is needed before the request is moved. Object and block still carry their ADT badges, so the code that is about to be overwritten can be opened in Eclipse right away (4.12).

You meet them in three places: the red banner on the report, which says how many there are and links here; this page, which lists them across the whole request; and the object itself, where they follow the reviewable blocks in red, tagged Violated — will be deleted / re-inserted / overwritten after TR move! depending on the case, so a diverging object cannot be reviewed without noticing it.

If the object shares no line at all with the remote one, the comparison is skipped: the object simply does not exist there (or is a different object under the same name), and reporting the whole file as a violation would only add noise.

📸 SCREENSHOT PLACEHOLDER — MOVING VIOLATIONS

image
5.7 Saving and reopening a review

The review is written as one JSON payload into ZAVE_REVIEW, one row per transport request. Approvals, declines, notes, comment threads, AI summaries and hunk statistics are all inside it.

Saving happens automatically and there is nothing to press: after every approve, decline, undo and comment, after a Prepare or a Recalc, and after an AI answer, the payload goes to the database. A session that ends unexpectedly loses nothing.

Two things make sure the automatic save is not silent about failure:

  • if the table ZAVE_REVIEW does not exist, the setup instruction (section 7) opens right when the review is opened — before any work is done,
  • if a save fails for another reason, you get a warning once per session instead of a lost review.

Entering the same request again opens the saved review straight away; from the object overview the Open Review button does the same. Obsolete state — approvals of hunks that no longer exist after a recalculation — is dropped on load.

5.8 What is excluded from a review

With Ignore SAP generated on (the default):

  • versions whose author matches SAP* — function group framework includes and similar,
  • generated Gateway/SEGW classes *_MPC, *_MPC_EXT and *_DPC,
  • the function group main program SAPL<area> — the include list SAP rewrites whenever a function module is added. It is stamped with the name of whoever added it, so the author rule never catches it, and all it ever shows is an INCLUDE line nobody wrote.

*_DPC_EXT holds hand-written code and stays reviewable. Unchecking the flag brings everything back into the review; objects excluded by a previous version of this rule are dropped from old saved reviews as well.

Independently of that flag, generator boilerplate is neutralized line by line — the SEGW header (This class has been generated on … in client …), the function group regeneration stamp (* regenerated at 30.06.2026 16:56:30) and the table maintenance generator header (generation date: …, view maintenance generator version: …). These are rewritten by every regeneration in every system, so left alone they turn a re-generated maintenance view into a change to approve, or into a moving violation whose whole content is the date it was generated on. The rule applies to the review diff and the retrofit diff alike.

5.9 Comment control

Off by default, switched on with Comment check (request no.) (P_CMTCHK) in the first block of the selection screen.

Most shops write the transport request number into the code itself: a change-history header at the top of the object, and a note behind the lines that were touched.

*----------------------------------------------------------------*
* 21-09-2020 |CTSRJXXX |ER6K947305| RITM0213358 - Additional fields
* 27-07-2026 |CT770028 |ER6K9A1JDL| DMND0004398 extra hiding
*----------------------------------------------------------------*
...
    it_rota_balan = lt_rota_balan.  " Added by CT813017 ER6K9A1JDL

With the flag on, AVE checks that habit and marks where it was not followed:

MarkWhereMeaning
⚠ no request numberend of the block header line, right after changes N, and next to the approve/decline controls of the full-source viewThe new lines of this block name no transport request in any comment.
⚠ no header change descrnext to the object name in the report, on the developer/reviewer pages and in the class viewThe request adds no description at the top of the object — see below.
⚠ wrong TRsame place as no request numberThe block names a transport request, but not the one under review.
⚠ no such TRsame placeThe block names a request of this system that does not exist here — the number is typed wrong.
Retrofit (orange)same placeThe block names a request of another system. Not a fault: it is code retrofitted from there, travelling on under our request.
Retrofit ✓ (orange)same placeThe same, and that request is in this object's own version history here — the code demonstrably did arrive from there.
⚠ N hunks without descrsame placeHow many changed blocks of that object carry no request number. Counted over the whole object, so the number does not change with the page you read it from.
⚠ N hunks with wrong TRsame placeHow many of them are documented under somebody else's request.
N hunks retrofit (orange)same placeHow many name a request of the other development system.

The two object findings are independent and can stand on one row: a request may write a proper header and still leave five blocks unannotated, or annotate every block and never touch the header.

The object mark is the stricter of the two, and deliberately so:

*----------------------------------------------------------------*
* Date       |Author   | Transport| Change ID - Description       *
* 08.07.2026 |CT818300 |ER6K9A1JDL| DMND0004398 - Rotation rest    *
*----------------------------------------------------------------*
MODULE status_0100 OUTPUT.        <- the first line of code ends the header

The description has to be an added full-line comment naming a request, standing in the leading comment area of the new source — before any code. A note behind a statement (et_rota_balan = DATA(lt_rota_balan). " Added by CT813017 ER6K9A1JDL) satisfies the per-block rule but is not a description of the object: whoever opens it still finds nothing at the top. A full-line comment 400 lines down is not the header either.

The statement that opens the part — REPORT, FUNCTION, METHOD, MODULE, FORM, CLASS, INTERFACE — does not end the leading area, so a method may carry its block under its own METHOD line.

What counts is the CTS number itself — <SID>K<6>, e.g. ER6K947305 or ER6K9A1JDL, in an ABAP comment (* line or " note) or a CDS one (//). The ticket ids written next to it (RLSE0027352, DMND0004398) are a per-shop habit; the request number is the one thing that ties the line back to what moves it. Case does not matter.

A block also never ends in the middle of an ABAP statement: while the statement is unfinished the following lines belong to the block, and a change further down inside the same statement joins it rather than starting a new one. One comment on the opening line therefore covers the whole call — the closing ). on its own is not a separate change to document.

And it has to be the right number — letter for letter. The named request is compared with what was entered on the selection screen, and nothing on the found side is resolved into anything else. Enter a request and only that request passes; enter a task and its parent request passes with it. What this buys is the finding the whole check exists for: a number one character off — ER6K9A1JDT written all over a review of ER6K9A1JDL — which reads perfectly right and no reviewer catches by eye.

The red case therefore splits three ways, and the badge says which:

no such TRour SID, no such request in this system → the number is typed wrong.
task, not TRthe number is a task (S/R). The convention writes the transport request the work moves under, not the task it was typed in.
wrong TRa request of this system that exists and is not this review's.

A block naming both a foreign number and one of ours passes; the change is documented under this request whatever else stands next to it. Without a request scope (package or plain object review) there is nothing to be wrong against, and any number is accepted.

One foreign number is not a fault, and is marked orange instead of red: a request of another system. " Added by CT813017 ER4K991928 inside a review of an ER6 request is retrofitted code — written there, carried on here — and the reviewer wants to see that, not to be told it is wrong.

No remote system has to be entered for this, and nothing is read from that system: the first three characters of a CTS number are the system it was created in, so a number whose SID is not this system's cannot be a request of this system at all. And for a number that does carry our own SID the existence check is local — E070 in this system either has it or does not. That splits the red case in two:

no such TRour SID, no such request here → the number is typed wrong. ER6K9A1JDT in a review of ER6K9A1JDL lands here — the hardest of the four verdicts, because it needs no interpretation.
wrong TRour SID, the request exists, but it is not this review's → the change is documented under somebody else's request.

A request of another system cannot be verified in E070 — that table is local and its absence proves nothing — but it leaves another trace: an import writes the source request into the version history, which is why the retrofit baseline can be found by request number at all (5.6). So the object's own versions are asked as well, and a foreign number found among them turns the note into Retrofit ✓ — the code did travel from there. Not found, it stays a plain Retrofit: that request may have touched other objects only, so absence faults nothing.

On an object row both red cases are counted together as N hunks with wrong TR, and both orange ones as N hunks retrofit; which of the two it is, the block's own badge says.

Two consequences worth knowing before you switch it on:

  • A block that only deletes lines has no new line to name the request on, so it is always marked. That is the intended answer: removed code is commented out with the request number, not silently dropped.
  • Class sections (CPUB / CPRO / CPRI, and the CLSD definition) are exempt. They hold declarations, not code, SAP regenerates them in an arbitrary order, and there is no place in them for a change-history line — the convention lives in the method that uses the declaration. So is the function group main program SAPL<area>, for the same reason — although with Ignore SAP generated on it never reaches the review at all (5.8).
  • Moving violations are never marked — they are not somebody's change, so nobody owes them a comment. Neither are DDIC objects (a table or domain has no source line to write a comment on).

The verdict is decided while the review is prepared, so the flag can be ticked on a review that already exists — no recalculation needed. Reviews saved before this check existed carry no verdict and stay unmarked until their objects are computed again; an unchecked block must not read as a failed one.


6. AI-assisted review

ASK AI on a single hunk sends that block alone; the link appears only when the AI block above is filled in. Above the block list there are two prompt buttons that cover everything visible in the current view:

ButtonWhat lands in the prompt
AI prompt diffThe changed blocks only — short and cheap, enough for "what changed here".
AI prompt fullThe whole source of every touched object with the changes marked (+ added, - deleted, the rest is context) — costs tokens, but the model judges a change in its surroundings instead of in isolation.

Both are pages you can read, with Save to file and Copy to clipboard on top; the button decides what goes in, not the Compact toggle. Each prompt states what the model is looking at — the changed blocks only, or the full source — and what the markers mean: + is a line of the new version, - a line of the previous one, and a block holding both is a modification. When the AI API block is filled in, the first button turns into AI Summary and AVE calls the provider itself, storing the answer as a comment in the hunk thread or as a persisted AI summary of the object — AI prompt full stays a copyable page in that case too.

A review profile is a pair of files in one frontend folder, matched by name:

<profile>.md     the system prompt — persona, what to look for, what to ignore  (required)
<profile>.json   the JSON schema the answer must conform to                     (optional)

The profile owns the instructions; AVE owns the material — object name and changed lines — and passes it as the user turn. A profile without a schema simply asks for free-form text.

The system prompt is resolved in three steps, first hit wins:

  1. System prompt file — the .md file named on the selection screen,
  2. Review profile — <profile>.md in the profiles folder,
  3. the instruction text built into the report, kept as prompts/ave_system.md so it can be read, edited or used as the start of your own profile.

The folder is read from the frontend, so it lives on the machine running SAP GUI. Files are read once per run and cached — leave and re-enter the report to pick up an edit.

Two ready-made profiles ship in prompts/: rules and security.


7. ZAVE_REVIEW table setup

The Code Reviewer can store its data only after a transparent table ZAVE_REVIEW exists and is active. The design is deliberately minimal: one row per transport request and remote system, the full review with its save history in one JSON payload.

FieldTypePurpose
MANDTMANDTClient field (key)
TRKORRTRKORRTransport request (key)
REMOTEVERSSYSNAMRemote system of the comparison (key), empty for a review without one
PAYLOADSTRINGReview JSON including the current state and the save history
  1. Create transparent table ZAVE_REVIEW.
  2. Make MANDT, TRKORR and REMOTE key fields.
  3. Add field PAYLOAD of type STRING.
  4. Activate the table. No ZIP or compression is needed.
  5. Return to AVE and open the review again.

Why REMOTE is part of the key. The reviewable blocks are identical with and without a remote system, but the row is not: a review run against another system also carries that system's moving violations and the diffs behind them (5.6), and a second remote system produces a third set. One row per request and target system keeps them apart instead of letting the last run overwrite the others.

Extending a table created before this field: add REMOTE (data element VERSSYSNAM) as the third key field and activate. Rows saved earlier keep their reviews — the field comes up empty, which is exactly what a review without a remote system uses.

The field is required, not optional. Until it exists AVE stores nothing and the setup page keeps coming up. There is deliberately no fallback to the two-field key: with it the plain review and the one compared against another system share a single row and overwrite each other, whichever ran last.

Opening a review without the table shows this same help page inside AVE.


8. Also in this repository

Two side tools, neither of them needed to run AVE:

  • Z_AVE_OBSERVER — alpha 0.5. A companion report that observes workbench (K) requests changed or released in a date range, filtered by package and user, and lets you browse their objects with a quick diff indicator; clicking an object opens the real diff, rendered by AVE's own engine. Standalone version: src/z_ave_observer_sa.prog.abap.
  • html_simulator/ — a browser-side port of the diff algorithm, for trying the diff behaviour out without a SAP system. Open html_simulator/index.html directly in a browser, no build step.

And as a bonus, a standalone HTML/JS local comparer: https://github.com/ysichov/Diff


Written by Yurii Sychov

Inspired by abapTimeMachine, Eclipse ADT, GitHub and all other similar tools.

MIT, read

History

Latest

v0.9

Notes

Testing release possibilities

Code review
  1. abapTimeMachineShows a whole ABAP object as it stood at a past version
  2. abap-transport-reviewTransport release check gated by GitHub pull request approval
  3. abapOpenReviewSAP GUI code review tied to transport release
  4. VERTEXADT extension for Eclipse and VS Code showing three SAP GUI tools

Details

Sources3
Added by handdiscovered herechecked
github.com/ysichov/AVEtree, pushes, contributors, CIchecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
discovered viaAdded by hand
first seen in the atlas
ecosystem and domainabap, developer-experience
abaplint
issues under its own abaplint configuration25,457
lines85,541
statements55,290
objects56
files108
analysed, main
abaplint version2.120.84
Flavors1
Standard ABAP
“SAP ABAP version explorer and code review tool for SAP GUI.” — ysichov/AVE — READMEchecked
History in the atlas2
  1. Versions, diffs and saved reviews also show in Eclipse ADT and VS Code through [VERTEX](artifact:ysichov-vertex), where a block can be approved, declined and commented on as well.
  2. First seen.
For your agent