mirror of
https://github.com/GMGNAI/gmgn-skills.git
synced 2026-11-02 07:46:11 +00:00
Re-audit of the change in this PR, all four in code or claims the PR itself introduced. 1. A creation time that was not a readable number crashed the whole run. A string-typed timestamp in `created.json` raised `TypeError: unsupported operand type(s) for -: 'float' and 'str'` out of `creage()` and took the entire scoring pass with it, instead of dropping one row. The loader now coerces once, up front. 2. Worse than the crash: the values that did NOT crash were accepted and silently moved the list. `NaN` compares False against everything, so it passed the track test as "not young" AND came out of the freshness clamp at 1.0 — the easier mature track and a full newborn bonus at the same time, which is precisely the bug this PR exists to remove. A negative or absurdly small number read as "very old" and also bought the mature track. Unreadable is now stored as None (asked, no answer), which falls back to open time and keeps the row on the stricter track. Verified against string / list / NaN / negative / float / null / bool / zero / future-dated: nine cases, no crash, and every unreadable one now resolves in the strict direction instead of the generous one. 3. A lookup that never landed was indistinguishable from one that came back empty, and both were written as null. Exit status cannot separate them — `gmgn-cli token info` answers 0 with a fully zeroed body for an address it does not know (measured: `creation_timestamp: 0`, empty stderr). So the body itself decides: one that parses and echoes the address back is a real answer and a zero creation time is written as null, while one that does not parse or does not echo it back is a call that never landed, is left out of `created.json` entirely, and is named on stdout so Step 3 lists it again rather than scoring the row off an age nobody read. Step 3b also keeps its stderr now, in an `.err` file beside the response, the way Step 1 does, instead of sending it to /dev/null. 4. The report could state an age that was off by weeks. The table's age column is the pool-open age, which is right for the 7-day ceiling, but after this PR a token can be listed whose real age is far older — and nothing printed that number, so the writer could not have known. arc/ARGUS would have been reported as "1.9d" on a list whose headline promise is recency, when the token is 19.5 days old. The address line now prints `created=N.Nd ago` whenever the two differ by more than a day, and stating it is required in `## What the answer has to contain`. Two claims elsewhere in the file that this PR had made false are corrected rather than left to contradict it: the ceiling bullet said `MAX_AGE_D` stops a months-old token reaching the list, which is now true only of months of trading and not of the token's age, and the `YOUNG_D` cliff note did not say which of the two ages the cliff is measured on. No threshold, weight, gate constant or routing description changes. Against the same saved 7-chain sweep, pass 1 names the same 5 rows and pass 2 returns the same 4 names in the same order. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>