# johmara/agentic-traceability-maintenance-dataset
Manual Audit

Agent-HAnS Annotation Audit

Agent-HAnS writes annotations automatically as an AI coding agent builds an app. This page is a manual, line-by-line check of every annotation it wrote in ReferenceManager, to see how well the automation actually held up.

How to read this page

Agent-HAnS uses three kinds of markers, called embedded feature annotations, to record which feature a piece of code belongs to. A folder mapping tags a whole folder. A file mapping tags a whole file, listed in a small companion file named .feature-to-file. A fragment mapping tags a specific block or line of code with a comment such as &begin[Groups] ... &end[Groups], or &line[Groups] for a single line. All of them point at an entry in .feature-model, the tree of every feature in the app.

For every annotation we checked two things. First, does the feature it points at still exist? A merge or a split can remove a feature, leaving old annotations pointing at nothing, we call that stale. Second, assuming the feature does exist, does the annotated code actually implement it? If the code doesn't match, or the annotation covers more than it should, we call that misplaced. Everything else is correct. A begin/end block is also either balanced, meaning its &begin has a matching &end, or not.

Jump to:

Final feature model (.feature-model)

ReferenceManager
    Database
    ApiDocs
    Versioning
    Papers
        CreatePaper
        GetPaper
        UpdatePaper
        DeletePaper
        ImportBibtex
        ExportBibtex
        SearchPapers
    Authors
        CreateAuthor
        GetAuthor
        ListAuthors
        UpdateAuthor
        DeleteAuthor
        MergeAuthors
    Groups
        CreateGroup
        GetGroup
        UpdateGroup
        DeleteGroup
        AddPaperToGroup
        RemovePaperFromGroup

25 non-root features, 6 top-level. Tags and Collections existed earlier and were merged into Groups at Evolution 5; Authors was promoted from Papers.Authors to top-level at Evolution 8 (split). Note that Authors has a dedicated ListAuthors feature, but Papers and Groups do not have a corresponding ListPapers / ListGroups — this asymmetry turns out to matter below.

Summary

25features in final model
14 / 20file mappings correct
6 / 20file mappings stale
36 / 36begin/end blocks balanced
3 / 36blocks misplaced or over-broad
25 / 25features covered by fragments

Being balanced and pointing at a real feature name is a low bar, every begin/end block clears it, and every referenced feature name exists. But reading the actual code inside each block tells a stricter story: 3 of the 36 blocks (8%) are tagged with a feature their code doesn't actually implement. The two charts below show both counts side by side, the two mapping mechanisms Agent-HAnS uses (whole-file mappings and in-code fragment markers) land at different accuracy.

File-to-feature mappings20 total
14 correct
6 stale
Fragment begin/end blocks36 total
33 correct

File-level mappings (.feature-to-file) — 20 total

FolderFileMapped featureVerdictReason
DataAppDbContext.csDatabasecorrectFeature exists, mapping matches file content.
DataDbSeeder.csDatabasecorrectFeature exists, mapping matches file content.
EndpointsPaperEndpoints.csPaperscorrectFeature exists, mapping matches file content.
EndpointsGroupEndpoints.csGroupscorrectFeature exists, mapping matches file content.
Migrations20260424105228_AddCollections.csCollectionsstaleCollections no longer exists — merged into Groups at Evolution 5. Dangling reference.
Migrations20260424105228_AddCollections.Designer.csCollectionsstaleSame as above.
Migrations20260427060630_AddTags.csTagsstaleTags no longer exists — merged into Groups at Evolution 5. Dangling reference.
Migrations20260427060630_AddTags.Designer.csTagsstaleSame as above.
Migrations20260427075843_MergeTagsAndCollectionsIntoGroups.csGroupscorrectFeature exists, this is the merge migration itself.
Migrations20260427075843_MergeTagsAndCollectionsIntoGroups.Designer.csGroupscorrectSame as above.
ModelsPaper.csPaperscorrectFeature exists, mapping matches file content.
ModelsAuthor.csPapersstaleAuthors was promoted to top-level at Evolution 8; mapping was never updated. The fragment annotation in this same file correctly says &begin[Authors] — the two annotation layers disagree inside one file.
ModelsAffiliation.csPapersstaleSame split-related staleness as Author.cs.
ModelsGroup.csGroupscorrectFeature exists, mapping matches file content.
RequestsPaperRequests.csPaperscorrectFeature exists, mapping matches file content.
RequestsGroupRequests.csGroupscorrectFeature exists, mapping matches file content.
ResponsesImportResult.csImportBibtexcorrectSub-feature of Papers, exists, mapping matches.
ResponsesSearchResponse.csSearchPaperscorrectSub-feature of Papers, exists, mapping matches.
ServicesBibtexParser.csImportBibtexcorrectSub-feature of Papers, exists, mapping matches.
ServicesBibtexSerializer.csExportBibtexcorrectSub-feature of Papers, exists, mapping matches.

Do the annotations point at the right code?

Checking that &begin[Groups] names a feature that exists is a name lookup, it does not tell you whether the code between &begin[Groups] and &end[Groups] actually implements Groups. To check that, we read every one of the 36 blocks by hand against the code it wraps. Three resolve to a real feature yet are misplaced, meaning the code inside doesn't match, or over-broad, meaning the block covers more than the one feature it names.

1. Data/DbSeeder.cs:118–159 tagged Groups, but the code creates Paper objects

// &begin[Groups]
new Paper
{
    Title = "On Using LLMs to 'Featurize' Software",
    ...
},
new Paper { Title = "An IDE Plugin for Clone Management...", ... },
new Paper { Title = "Visualizing Feature-Oriented Software Evolution", ... },
... (4 more Paper object literals)
// &end[Groups]

No Group entity is constructed anywhere in this block — it is pure Paper seed data. It happens to seed the exact papers that a later, separate block (lines 165–192, correctly tagged Groups) assembles into a demo Group. The annotation likely followed "this data exists in service of the Groups demo" rather than "this code implements the Groups feature." By the paper's own definition, feature annotation should track where a feature's implementation asset lives, not where its test data originates — this block should be untagged or tagged Papers.

2. Endpoints/GroupEndpoints.cs:13–30 tagged GetGroup, but contains two distinct endpoints

// &begin[GetGroup]
app.MapGet("/groups", ...)          // list all groups — named "ListGroups"
    .WithName("ListGroups")...

app.MapGet("/groups/{id:int}", ...) // get one group — named "GetGroup"
    .WithName("GetGroup")...
// &end[GetGroup]

The block covers both the collection-list endpoint and the single-item endpoint, but only GetGroup exists in the model — there is no ListGroups. The list endpoint's code is absorbed into a tag that names something narrower than what it covers.

3. Endpoints/PaperEndpoints.cs:14–31 tagged GetPaper, same pattern

// &begin[GetPaper]
app.MapGet("/papers", ...)          // list all papers — named "ListPapers"
    .WithName("ListPapers")...

app.MapGet("/papers/{id:int}", ...) // get one paper — named "GetPaper"
    .WithName("GetPaper")...
// &end[GetPaper]

Identical issue to finding 2. Together these two findings show a systematic gap: 2 of 3 CRUD feature families (Papers, Groups) never got a ListX sibling feature the way Authors did, so the agent folded list-endpoint code into the closest existing tag instead of extending the feature model to match. This is a modeling-granularity miss carried consistently across two evolution steps (Evolution 1 for Papers, Evolution 2 for Collections/original Groups precursor), not a one-off slip.

Everything else checked out

The remaining 33 of 36 blocks were read in full and match their tags: all Authors/CreateAuthor/GetAuthor/UpdateAuthor/DeleteAuthor/ListAuthors/MergeAuthors blocks in AuthorEndpoints.cs correctly scope to their named operation (this family does distinguish List from Get). The nested MergeAuthors block inside the outer Authors block in the test file is correctly nested. All Program.cs, Requests/, Responses/, and Models/ (except Author.cs's file-mapping conflict, already listed above) blocks match their code exactly. All 14 &line[F] annotations sit on the correct line and name the correct feature.

Full fragment list — 36 begin/end blocks + 14 line annotations

FileLineKindFeatureResolutionPlacement
Data/AppDbContext.cs9lineGroupsexistscorrect
Data/AppDbContext.cs10lineAuthorsexistscorrect
Data/AppDbContext.cs14 / 22begin/endAuthorsexistscorrect
Data/AppDbContext.cs24 / 29begin/endGroupsexistscorrect
Data/DbSeeder.cs12 / 51begin/endAuthorsexistscorrect
Data/DbSeeder.cs118 / 159begin/endGroupsexistsmisplaced — creates Papers, not a Group
Data/DbSeeder.cs165 / 192begin/endGroupsexistscorrect
Endpoints/AuthorEndpoints.cs12 / 17begin/endListAuthorsexistscorrect
Endpoints/AuthorEndpoints.cs19 / 26begin/endGetAuthorexistscorrect
Endpoints/AuthorEndpoints.cs28 / 43begin/endCreateAuthorexistscorrect
Endpoints/AuthorEndpoints.cs45 / 61begin/endUpdateAuthorexistscorrect
Endpoints/AuthorEndpoints.cs63 / 75begin/endDeleteAuthorexistscorrect
Endpoints/AuthorEndpoints.cs77 / 104begin/endMergeAuthorsexistscorrect
Endpoints/AuthorEndpoints.cs107 / 144begin/endAuthorsexistscorrect
Endpoints/GroupEndpoints.cs13 / 30begin/endGetGroupexistsover-broad — also covers ListGroups (no such feature)
Endpoints/GroupEndpoints.cs32 / 42begin/endCreateGroupexistscorrect
Endpoints/GroupEndpoints.cs44 / 57begin/endUpdateGroupexistscorrect
Endpoints/GroupEndpoints.cs59 / 71begin/endDeleteGroupexistscorrect
Endpoints/GroupEndpoints.cs73 / 90begin/endAddPaperToGroupexistscorrect
Endpoints/GroupEndpoints.cs92 / 107begin/endRemovePaperFromGroupexistscorrect
Endpoints/PaperEndpoints.cs14 / 31begin/endGetPaperexistsover-broad — also covers ListPapers (no such feature)
Endpoints/PaperEndpoints.cs33 / 57begin/endCreatePaperexistscorrect
Endpoints/PaperEndpoints.cs59 / 82begin/endUpdatePaperexistscorrect
Endpoints/PaperEndpoints.cs84 / 96begin/endDeletePaperexistscorrect
Endpoints/PaperEndpoints.cs98 / 179begin/endImportBibtexexistscorrect
Endpoints/PaperEndpoints.cs181 / 238begin/endSearchPapersexistscorrect
Endpoints/PaperEndpoints.cs240 / 256begin/endExportBibtexexistscorrect
Models/Author.cs3 / 12begin/endAuthorsexistscorrect (contradicts stale file mapping, see above)
Models/Paper.cs7lineAuthorsexistscorrect
Models/Paper.cs11lineImportBibtexexistscorrect
Models/Paper.cs12lineImportBibtexexistscorrect
Models/Paper.cs13lineGroupsexistscorrect
Program.cs10 / 14begin/endApiDocsexistscorrect
Program.cs18 / 21begin/endDatabaseexistscorrect
Program.cs25lineApiDocsexistscorrect
Program.cs27 / 33begin/endApiDocsexistscorrect
Program.cs37 / 44begin/endDatabaseexistscorrect
Program.cs46lineVersioningexistscorrect
Program.cs48lineAuthorsexistscorrect
Program.cs49lineGroupsexistscorrect
ReferenceManager.Tests/AuthorEndpointTests.cs9 / 229begin/endAuthorsexistscorrect
ReferenceManager.Tests/AuthorEndpointTests.cs115 / 227begin/endMergeAuthorsexistscorrect (correctly nested inside outer Authors block)
Requests/AuthorRequests.cs3 / 6begin/endAuthorsexistscorrect
Requests/PaperRequests.cs3 / 5begin/endPapersexistscorrect
Responses/PaperResponse.cs5 / 7begin/endAuthorsexistscorrect
Responses/PaperResponse.cs9 / 11begin/endGroupsexistscorrect
Responses/PaperResponse.cs16lineAuthorsexistscorrect
Responses/PaperResponse.cs20lineImportBibtexexistscorrect
Responses/PaperResponse.cs21lineImportBibtexexistscorrect
Responses/PaperResponse.cs22lineGroupsexistscorrect

Feature coverage by fragment annotations

All 25 features in the model are referenced by at least one fragment annotation: Database, ApiDocs, Versioning, Papers, CreatePaper, GetPaper, UpdatePaper, DeletePaper, ImportBibtex, ExportBibtex, SearchPapers, Authors, CreateAuthor, GetAuthor, ListAuthors, UpdateAuthor, DeleteAuthor, MergeAuthors, Groups, CreateGroup, GetGroup, UpdateGroup, DeleteGroup, AddPaperToGroup, RemovePaperFromGroup. 25/25 — full coverage, independent of the placement findings above (coverage counts a feature as "referenced" even where the reference is over-broad, e.g. GetGroup / GetPaper).

Coverage-by-feature is not the same question as coverage-by-file. A feature can be "covered" by one annotated file while a second file that also implements it carries nothing. The section below checks the latter.

Files that should have an annotation but don't

So far, every check has started from an annotation that exists and asked whether it's correct. This section asks the reverse question: are there files that clearly implement a feature, yet carry no annotation at all? Of the 41 .cs files in ReferenceManager, 23 carry at least one annotation and 18 carry none. Most of the 18 are legitimately infrastructural, files a human wouldn't annotate either, such as EF-generated *.Designer.cs siblings of already-tagged migrations, the auto-generated AppDbContextModelSnapshot.cs, the test-harness CustomWebApplicationFactory.cs, the three endpoint test suites (discussed separately below), and the generic cross-feature Responses/PagedResult.cs. Two are not, and those two are real gaps.

Test files are excluded from this check by design. Embedded feature annotations track where a feature is implemented, and tests verify a feature rather than implement it, so an unannotated test suite is not a recall failure. The interesting fact about the test suites turns out to run the other way, see below.

23 / 41files carry some annotation
2feature-implementing migrations, zero annotation

4. Migrations/20260427094357_StandaloneAuthors.cs (+ .Designer.cs) — the Evolution 8 split migration itself, completely untagged

public partial class StandaloneAuthors : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.CreateTable(name: "Authors", ...);
        migrationBuilder.CreateTable(name: "PaperAuthor", ...);
        // ... migrates existing JSON-embedded authors into standalone rows ...
        migrationBuilder.DropColumn(name: "Authors", table: "Papers");
    }
}
// no &begin[Authors] anywhere in this file

This is the migration that performs the Evolution 8 split promoting Authors to a top-level feature, the same structural change that left Models/Author.cs and Models/Affiliation.cs mapped to the wrong feature (finding above). It is the third distinct annotation failure traceable to that single evolution step, and arguably the most direct one, since this file is the split.

5. Migrations/20260427081828_AddJournalAndBooktitleToPaper.cs (+ .Designer.cs) — adds the exact columns tagged ImportBibtex elsewhere, but is itself untagged

public partial class AddJournalAndBooktitleToPaper : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<string>(name: "Booktitle", table: "Papers", ...);
        migrationBuilder.AddColumn<string>(name: "Journal", table: "Papers", ...);
    }
}
// no &line[ImportBibtex] anywhere in this file

Models/Paper.cs:11-12 tags the Journal and Booktitle properties &line[ImportBibtex], and Responses/PaperResponse.cs:20-21 does the same. The migration that adds these exact two columns to the database has no annotation at all, so the schema-level half of this feature's traceability is missing while the model- and response-level halves are present.

Aside: AuthorEndpointTests.cs is the outlier, not PaperEndpointTests.cs / GroupEndpointTests.cs

Test fileLinesAnnotation
AuthorEndpointTests.cs229&begin[Authors] / &begin[MergeAuthors] — tagged, arguably shouldn't be
PaperEndpointTests.cs118none, consistent with test files being out of scope
GroupEndpointTests.cs160none, consistent with test files being out of scope

Given that test files are out of scope for embedded feature annotation, the odd one out is AuthorEndpointTests.cs, which the agent annotated anyway during the Evolution 8 split, not the other two suites lacking annotation. This is an inconsistency in what the agent chose to tag, not a coverage gap, and it is the same asymmetry between Authors and Papers/Groups seen in the ListAuthors vs. missing ListPapers/ListGroups finding above, surfacing here as over-annotation rather than under-annotation.

Softer, contextual migration cases — judgment calls, not counted as failures

Migrations/20260424100356_InitialCreate.cs (the original bootstrap migration for Database/ApiDocs/Papers) and Migrations/20260424100754_AddAuthorModel.cs / 20260424101024_AddMultipleAffiliations.cs (pre-split author migrations, together 96 lines) carry no annotation either, but they predate most of the feature model's granularity and are harder to fault under the notation as it existed at the time they were written.