import json
p='/tmp/pom-tests-backend-app.json'; a=json.load(open(p))
# Keep internals reserved for source/layout assertions or assertions about the test harness itself.
internal_names={
'TestJournalAuthorOnlySQL_FixtureUUIDsAreHex',
'TestTodosAuthorOnlySQL_FixtureUUIDsAreHex',
'TestNoInboundMailImportPath',
'TestKindSQLFixtureHelperIsLoopbackOnly',
'TestKindSQLFixtureRejectsLibpqRedirectors',
'TestSessionReadSkipsOwnNameRPCs',
'TestApplyStepInStartupInjectsCodeSecret',
'TestExtractDispatcherStartupPolicy',
'TestMainWiresStepInStartup',
'TestMergeEnvFileLocalWinsOverDotenvForUnsetKeys',
'TestLoadCastEnvKeepsExportedSupabaseURL',
'TestHandleMe_CastDaveAndEmilyIsolation', # end-to-end auth/data separation has internal fixture details, so mixed below
}
# Explicit semantic purpose corrections for the weakly named candidates.
purpose={
'TestJournalAuthorOnlySQL_FixtureUUIDsAreHex':'Validate UUID fixtures embedded in the author-only SQL test file',
'TestTodosAuthorOnlySQL_FixtureUUIDsAreHex':'Validate UUID fixtures embedded in the author-only SQL test file',
'TestNoInboundMailImportPath':'Ensure the server package does not import the retired inbound-mail path',
'TestCastAPIParserRefusesUnsafeTargets':'Reject non-loopback or credential-bearing cast API targets without leaking secrets',
'TestCastAPISQLStackMustMatch':'Reject cast API and SQL targets that point at different local stacks',
'TestCastAPIRefusesConflictingCredentialAliases':'Reject conflicting credential environment aliases without exposing values',
'TestHandleItems_CastDaveEstatePacketUploadPipeline':'Exercise an estate-packet upload through extraction, typed summary, and published item reads',
'TestHandleItems_CastDaveEstatePacketUploadCitationPipeline':'Exercise an estate-packet upload and verify citations survive into the published result',
'TestBindOptionalJSON_EmptyBodyPreserved':'Accept an absent optional JSON body while leaving generation unset',
'TestBindOptionalJSON_ReadsExpectedGeneration':'Decode expected-generation from the optional JSON body',
'TestFirst72HoursGuideGoldenKeys':'Decode the guide fixture, enforce required fields, and reject unknown or legacy keys',
'TestFirst72HoursGuideStructKeysMatchAllowlist':'Keep guide and contact JSON tags aligned with the published key allowlists',
'TestFirst72KeyListsHaveNoDuplicates':'Reject duplicate names in the guide JSON key allowlists',
'TestFirst72HoursGuideContactsFieldType':'Require the guide contacts field to have the contact-slice type',
'TestTitleCaseIfAllCapsMatchesNameSplitCases':'Match the shared name-splitting/title-case cases for all-caps names',
'TestTestSQLShippedTypesEqualDefaultSupportedTypes':'Compare live shipped document types with the Go supported-type registry',
'TestSQLNoAccountFamilyPublishesOwnershipForm':'Verify the live catalog and writer gate no longer publish account ownership form',
'TestKindSQLFixtureHelperIsLoopbackOnly':'Require SQL fixture commands to use the explicit loopback target and safe psql flags',
'TestKindSQLFixtureRejectsLibpqRedirectors':'Reject inherited libpq environment settings that could redirect SQL fixtures',
'TestFirst72HoursGuideGoldenKeys':'Decode the golden guide payload and reject omitted, legacy, or extra JSON keys',
'TestItemConfirmationState_DecodesGenerationWithPersistentState':'Decode confirmation generation and persistent state while keeping generation out of nested public metadata',
'TestCurationSerializationConflict_IsRetryableAndRedacted':'Map a serialization conflict to a retryable public error without exposing database detail',
'TestNoOneNamedSortsBeforeNotAccepted':'Sort an unnamed person ahead of a person who has not accepted',
'TestGetSessionByAuthUserID_AuthIdentityFailureOmitsIncomingInvites':'Omit incoming invites when the authenticated identity lookup fails',
}
# Mark tests whose source bodies were directly inspected in this follow-up. Others retain an explicit heuristic label.
reviewed={
'TestJournalAuthorOnlySQL_FixtureUUIDsAreHex','TestTodosAuthorOnlySQL_FixtureUUIDsAreHex','TestNoInboundMailImportPath',
'TestCastAPIParserRefusesUnsafeTargets','TestCastAPISQLStackMustMatch','TestCastAPIRefusesConflictingCredentialAliases',
'TestBindOptionalJSON_EmptyBodyPreserved','TestBindOptionalJSON_ReadsExpectedGeneration',
'TestFirst72HoursGuideGoldenKeys','TestFirst72HoursGuideStructKeysMatchAllowlist','TestTitleCaseIfAllCapsMatchesNameSplitCases',
'TestConfirmRecordsHubItem_SendsRequiredNullGeneration','TestCurationSerializationConflict_IsRetryableAndRedacted','TestItemConfirmationState_DecodesGenerationWithPersistentState',
'TestReadReceiptCommitCountsExtractOCR','TestReadReceiptPinnedCollisionsAndReplay','TestSQLShippedTypesEqualDefaultSupportedTypes','TestSQLNoAccountFamilyPublishesOwnershipForm',
'TestMemberFinancialAccountIsTheOnlyWriterFamily','TestNewRouterOmitsStepsInNudge','TestNewRouterOmitsGraphEntitiesMerge','TestNewRouterMountsGoneMetadataDocumentTypes',
'TestMainWiresStepInStartup','TestExtractDispatcherStartupPolicy','TestApplyUserCorrectionRPC_HitsRPCWithRightPayload',
}
# Tests that are genuinely mixed: user-visible result plus an asserted internal side effect/request/state.
mixed_keep={
'TestHandleAccess_CastShareInviteLockGrant','TestHandleAccess_CastDeathClaimExport','TestHandlePeople_CastRosterUsesResolvedReachablePeople',
'TestHandleFacts_CastPinVersusNewerAndEmilyIsolation','TestHandleFacts_CastManualWritePinConfirm','TestHandleItems_CastDaveListsAndOpensSeed',
'TestHandleItems_CastDaveCreateDeleteNote','TestHandleItems_CastDaveUploadsPDF','TestHandleJournal_CastDaveCRUDShannonCannotRead',
'TestHandleMe_CastUnknownJWTDoesNotMint','TestM1C_SharedSparseRecords','TestM1F_SQLFailureAbortsUncommittedSave',
'TestHandleAddPerson_CastWritesAssertionTwins','TestRemovePerson_SQLNotFoundAndNonUUID','TestHandlePeople_CastAcceptedExecutorSafeNameAndPlansRole',
'TestHandlePeople_CastOursTwoOwnerEvidenceDoesNotCross','TestHandlePeople_CastPublishedRoleFamilies','TestHandlePeople_CastWrongSubjectDoesNotInventExecutor',
'TestM2A_InviteSignupKeepsStructuredParts','TestM2AW_SnapshotReadbackAndStaleCAS','TestHandleCreateSpouseInvite_DoesNotClaimSentWhenRPCFails',
'TestHandleCreateSpouseInvite_EarlyAndRPCPendingMatch','TestStepInRaiseRejectsUnknownKeyWithoutRPC','TestStepInQueueAndCaseShowPendingRefusal',
'TestHandleTodos_CastDaveCRUDShannonCannotRead','TestHandleWorthALook_QueryDTO','TestFilesRoutesAreGone','TestHomeSummaryRouteIsGone',
'TestPeopleRoutesReachTheHandlers','TestStaffRoleRoutes','TestInviteContactVerificationResendPayloadAndCIGuard',
'TestUpsertIngestFailure_HitsRPCWithRightPayload','TestListRetryCandidates_QueryShape','TestGetItemKindOutcomes_HTTPJSON',
'TestSessionSpouseNameRPCErrorLoadsSomeone','TestGetSessionByAuthUserID_AuthIdentityFailureOmitsIncomingInvites',
'TestSessionNamedToStepInReadErrorLeavesFlagFalse','TestOrganicSignupUsesGoTrueRedirectQuery',
'TestApplyStepInStartupStoresSupportContact','TestWorthALookPropagatesMissingStepsInRPC','TestWorthALookOmitsEvidenceTheOwnerCanSee',
'TestTypedSummaryEvidenceWiringEnvelopeErrorHonest'
}
for x in a:
 n=x['name']
 if n in purpose: x['purpose']=purpose[n]
 if n in internal_names: x['classification']='internals'
 elif n in mixed_keep: x['classification']='mixed'
 elif x['classification'] in ('internals','mixed') and (n in purpose or n in reviewed): x['classification']='behavior'
 # The two endpoint/fixture tests are behavior despite SQL in their names.
 if n in {'TestReadReceiptCommitCountsExtractOCR','TestReadReceiptPinnedCollisionsAndReplay','TestCommitOCRCreatedAtIsBeforeCommittedAt','TestProducingJobGUCRestored','TestRelationChoicesMatchSQL','TestSQLShippedTypesEqualDefaultSupportedTypes','TestSQLNoAccountFamilyPublishesOwnershipForm'}: x['classification']='behavior'
 if n=='TestHandleMe_CastDaveAndEmilyIsolation': x['classification']='behavior'
 # Restatement is limited to concrete duplication/source assertions. These inspect outputs or fixtures, not production code.
 if x['restates']=='yes': x['restates']='no'
 if x['classification'] in {'internals','mixed'} or n in purpose:
  x['confidence']='reviewed' if n in reviewed else 'heuristic'
  x['execution_notes'] += ' Semantic follow-up confidence: '+x['confidence']+'.'
# Correct mistaken test-name purpose typo guard.
for x in a:
 if x['purpose'].startswith('TestTestSQL'): x['purpose']=x['purpose'].replace('TestTestSQL','Test SQL',1)
with open(p,'w') as f: json.dump(a,f,indent=2,ensure_ascii=False); f.write('\n')
from collections import Counter
print(len(a),Counter(x['classification'] for x in a),Counter(x['restates'] for x in a), 'flagged confidence',Counter(x.get('confidence') for x in a if x.get('confidence')))
