v3.13.3: ELF version retry for both P1 values + query-based per-AID budget

elfTagListRetry walks the untried tag-list forms for P1=10 and P1=20
(skipping combinations the main pass already refused via the expandedTried
map; only the tag-list forms are retried - the no-tag-list form never
carries CE - and the walk stops as soon as a version appears).  The form
memory can skip the tag-list forms for P1=10 when the Apps listing served
only the no-tag-list form (live 2026-10-02: EP BAP - its P1=10 tag lists
were never queried while the P1=20 retry refused them).

elfPerAidVersions filters to packages that actually have an applet
candidate before the six-query cap: the budget counts queries, not list
positions (EP BAP's first six packages are Oracle/JC-API entries with no
app instances - they consumed the cap and the A113 packages were never
queried).

Docs: help EN/RU, repo AGENTS (v3.13.3 note).  sw cache simple-v373.
Tests: 667 Python + 796 frontend green.
This commit is contained in:
2026-10-02 13:30:03 +03:00
parent 2c49c54d2d
commit cc480c30b7
7 changed files with 64 additions and 29 deletions
+9 -3
View File
@@ -939,10 +939,12 @@ test('ramStepLine names a bad-format failure instead of "PoR ok"', () => {
assert.ok(plain.includes('9000') || plain.includes('PoR ok'), plain);
});
test('the Explore retries the ELF tag lists with P1=20 and per applet AID', () => {
test('the Explore retries the ELF tag lists for both P1 values and per applet AID', () => {
const src = extractFunc(html, 'ramExplore');
assert.ok(src.includes('elfTagListRetry'), 'the P1=20 tag-list retry must exist');
assert.ok(src.includes("expandedPass('20'"), 'the retry must query P1=20');
assert.ok(src.includes('elfTagListRetry'), 'the tag-list retry must exist');
assert.ok(src.includes("for (const p1 of ['10', '20'])"), 'the retry must walk both P1 values');
assert.ok(src.includes('expandedTried[p1]'), 'already-tried forms must be skipped');
assert.ok(src.includes("['tags', 'noea', 'lean'].filter"), 'only the tag-list forms are retried');
assert.ok(src.includes('elfPerAidVersions'), 'the per-AID version queries must exist');
assert.ok(src.includes("ramExpandedQueryApdu('40', 'tags', false, app.aid)"),
'the per-AID query must use the AID filter');
@@ -950,6 +952,10 @@ test('the Explore retries the ELF tag lists with P1=20 and per applet AID', () =
'the module->applet mapping must be used');
assert.ok(src.includes('ramChainGetResponse(apdu)'),
'the single-AID 61xx answer must be fetched with a chained GET RESPONSE');
// the per-AID budget counts queries, not list positions (a package with
// no applet instance is skipped before the cap)
assert.ok(src.includes('if (app) missing.push({ elf: e, app: app });'),
'the per-AID candidates must be filtered before the cap');
});
test('every SCP80/RAM flow checks the low counter and stops', () => {