Conversation
Bumps the minor-and-patch group in /processor with 1 update: [github.com/go-telegram/bot](https://github.com/go-telegram/bot). Updates `github.com/go-telegram/bot` from 1.20.0 to 1.21.0 - [Release notes](https://github.com/go-telegram/bot/releases) - [Changelog](https://github.com/go-telegram/bot/blob/main/CHANGELOG.md) - [Commits](go-telegram/bot@v1.20.0...v1.21.0) --- updated-dependencies: - dependency-name: github.com/go-telegram/bot dependency-version: 1.21.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch ... Signed-off-by: dependabot[bot] <support@github.com>
Design spec for migrating the tracking/humans/profiles endpoint groups from hand-written Gin handlers to huma, for OpenAPI docs discoverability and a type-honest API while preserving the legacy wire envelope and lenient client tolerance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mutating the registry's stored *Schema for T contaminated strict handlers for the same type. Shallow-copy before flipping AdditionalProperties. Add a regression test proving a strict endpoint still 422s on unknown fields after a lenient registration of the same type, and harden the leniency test to assert decoded values. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… error message
huma's default schema-link transformer injected a $schema field into every
response body, breaking byte-compatibility of the legacy {status,...} envelope
on both success and error responses. Drop the transformer. Also fold huma's
per-field validation details into the legacy error message so 422s are no
longer the opaque "validation failed".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…o server
Wires NewHumaAPI into main.go (serving public /openapi.json and /docs) and
moves the pokemon-list endpoint from gin to huma as the worked-example
template. Legacy {status:ok,pokemon:[...]} envelope preserved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…y decomposition Single-object-or-array body, lenient item schemas (additionalProperties), and decomposition of the clean bitmask into caller-facing clean/edit/summary booleans (legacy integer clean still accepted), collapsed to the packed column. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ented defaults, debug logging profile_no/silent/suppressMessage modeled as optional (no -1/string-presence magic in the spec); body field server-defaults documented and pokemon_id marked required; restored debug body logging dropped in the gin->huma move; shared test helper + dead-var cleanup. Template hardened before the 9-type fan-out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ssage as bool profile_no now appears as type:integer in the spec (omit or 0 = active profile; profiles are 1-indexed). silent/suppressMessage are proper optional booleans instead of string-presence flags. Applied to GET and POST pokemon tracking. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…udit in real types Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…inconsistencies) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…er/league Reusable enum field types: canonical string enum in the OpenAPI, legacy integer (and numeric string) still accepted. Applied to pokemon gender and pvp_ranking_league. Shared toolkit for the tracking fan-out. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… section Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ecation stance, quest/nest/invasion fields) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ight from pokemon Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…-mega-evolution PR Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…es v1 silent+suppressMessage) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…i endpoints Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tance) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…CRUD (+new PUT) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…nt + frozen v1) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… full snapshot endpoint
Restore v1's per-user scoping (DeleteByUID is WHERE id AND uid). Path-scope rules under /api/v2/humans/{id}/tracking/{type}. Add GET /api/v2/humans/{id}/tracking full snapshot (human + tracking-by-type + profiles + locations + summaries; ?all_profiles, ?include_descriptions). Profiles become a human sub-resource.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… live path) Review Minor: processTestWeatherChange passed AlertType "weather"; every other derived type mirrors its live AlertType, and weather.go uses "weatherchange". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uilder)
Adds the "questSummary" derived DTS type to the enrich/test-command
unification work (superpowers/sdd task 5): a testdata.json partial
({reward:{type,reward,form}, quests:[...]}) drives enrichQuestSummary,
which re-enriches each quest via questEnrichOne and renders the group
through a new buildQuestSummaryGroupView helper factored out of the live
DispatchQuestSummary scheduler, so both paths build identical output.
questEnrichOne also now sets withAR itself (from the parsed webhook)
instead of requiring the caller to copy it from a buffered row, letting
the derived test path (with no buffered row) get it for free.
Wires enrichForType, EnrichWebhook, ProcessTest, and !poracle-test
(as "quest-summary", wire spelling "quest_summary" — mirroring the
fort-update/max-battle convention, since the command parser lowercases
args before matching validHooks, so a camelCase entry would never match).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wires the "monsterChanged" derived DTS test type end-to-end (superpowers/sdd
task 6): enrichMonsterChanged parses an {old,new} pokemon-webhook partial,
enriches `new` via the existing enrichPokemon path, and builds the
{{original.X}} prior-sighting view from `old` via the new
tracker.EncounterStateFromPokemon helper + dts.BuildOriginalView (the same
builder dispatchPokemonAlert's live change path falls back to).
- internal/tracker/encounter.go: factor the webhook->EncounterState mapping
out of ProcessPokemon into EncounterStateFromPokemon so both the live
pokemon handler and the new test builder share one implementation.
- cmd/processor/enrich.go: enrichMonsterChanged + enrichForType dispatch +
injectOriginalExtra (exposes original.* on the /api/dts/enrich flattened
variable map, which LayeredView.Flatten doesn't cover on its own).
- cmd/processor/test.go: processTestMonsterChanged builds an IsChange=true
RenderJob with OriginalView/ReplyKey so !poracle-test renders through
RenderPokemonChanged like a live change notification; wired into
ProcessTest and resolveDTSTypeFromRaw under the "monster_changed" wire
type.
- internal/bot/commands/poracletest.go: "monster-changed" CLI hook name,
resolveDTSType mapping, and disappear_time freshening for the `new` half
(deep-copied to avoid mutating the shared testdata sample).
- fallbacks/testdata.json: "monster_changed"/"ditto-reveal" sample — an
unencountered disguised Foongus revealed as an encountered Ditto, the
real-world scenario dispatchPokemonAlert's ChangeSpecies bucket exists for.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ch live render)
enrichMonsterChanged enriched `new` and built OriginalView from `old` but
never populated the per-language changeType/changeTypeText fields, so the
bundled monsterChanged templates' ungarded {{changeTypeText}} rendered a
dangling "— " on !poracle-test monster-changed,ditto-reveal. Compute the
species/stats bucket directly from the old/new EncounterState snapshots
(monsterChangedBucket) and reuse the live path's translation-key convention
(extracted into changeTypeText, shared with perLangWithChangeFields) to set
perLang["changeType"]/["changeTypeText"], threaded through to the RenderJob
via the existing renderJobFromEnrich copy. Also relabels the ditto-reveal
sample's location to "keep" since the relocate logic never reaches its
nested old/new lat/lon.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…leanTTH)
Adds the last derived poracle-test type: rsvpChanges reuses enrichRaid
wholesale (webhook.RaidWebhook already carries the rsvps array natively)
and layers on extras["overrideCleanTTH"], mirroring ProcessRaid's
latestFutureTimeslotSec computation. processTestRsvpChanges wires the
same raidlife:{gymID}:{raidEnd} EditKey/ReplyKey convention the live
rsvpChanges render job uses. Wires enrichForType, ProcessTest, and
poracletest.go (validHooks, resolveDTSType, timeslot freshening) for
the rsvp-changes/rsvp_changes/rsvpChanges spelling chain, plus a new
fallbacks/testdata.json sample and fixes a stale monsterchanged_test.go
assertion that assumed rsvpChanges was still unimplemented.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
GET /api/dts/testdata now accepts ?dtsType=<name>: resolves the name via the shared internal/dtsmap alias table and returns only the entries that preview that DTS type, each tagged with dtsType. Two source webhook types need a payload-shape split beyond a plain type match (mirroring resolveDTSTypeFromRaw): pokestop -> invasion/lure (by grunt vs lure fields) and raid -> raid/egg (by pokemon_id). The response also exposes the full DTS-type -> source map (webhookType, templateType, derived) so the editor can drop its hardcoded copy. The legacy ?type=<webhookType> filter is unchanged and untagged. Moved the canonical alias table (dtsSource/dtsAlias/dtsTypeMap) out of package main into internal/dtsmap so internal/api can share it without duplication; cmd/processor/dts_alias.go now re-exports thin wrappers so existing call sites and tests are unaffected. While wiring the table into testdata matching, corrected the four derived types' WebhookType values (monsterChanged/rsvpChanges/questSummary/ weatherchange), which had drifted to a hyphenated placeholder spelling that never matched the underscore/no-separator wire spelling testdata.json and !poracle-test actually use; added identity entries for both the CLI hyphenated form and the wire form so all spellings keep resolving. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… vs real testdata dtsmap's "fort-update" identity entry self-mapped WebhookType to the hyphenated "fort-update", which matches no testdata.json entry (the real type/wire spelling is "fort_update") — ?dtsType=fort-update silently returned zero results, breaking the DTS editor, which addresses the fort update template by its TemplateType name "fort-update". Same mismatch class Task 8 already fixed for the four derived types. Corrected the entry's WebhookType to "fort_update" so both "fort-update" and "fort_update" resolve identically; enrichForType's literal "fort_update"/"fort-update" switch and !poracle-test's dispatch were already spelling-agnostic and are unaffected. Added a regression-guard test that loads the REAL fallbacks/testdata.json and asserts every dtsmap.TypeMap() name resolves to at least one entry (except the documented nest/greeting exceptions), so a future testdata "type" rename or WebhookType typo can't silently break ?dtsType= filtering again. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Resolve the leading !poracle-test type token through the shared dtsmap alias table (case-insensitively, via a new AliasFold, since the bot parser lowercases every token before Run sees it) whenever it isn't already one of the existing raw wire-type/CLI-hyphenated spellings. This lets DTS template-type names like "monster", "maxbattle", "egg", and the lowercased "monsterchanged"/"rsvpchanges"/"questsummary" load the same testdata entry and dispatch the same wire type as their existing webhook-type/hyphenated forms. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Server contract for the DTS editor: DTS-name-addressable /api/dts/enrich, DTS-type-aware /api/dts/testdata (?dtsType + tags + types map), the derived-type partials, and the exact editor delete-list (hardcoded dtsToWebhookType map, client-side pokestop filter, monsterNoIv/egg special-casing). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iew includes synthetic PVP
Fix 1 (D6 completeness): RegisterTest (internal/api/huma_actions.go) passed
req.Type straight to ProcessTest, whose switch only accepts wire types.
POST /api/test {"type":"monsterChanged",...} 500'd with "unsupported test
webhook type", even though !poracle-test's resolveHookType already resolves
DTS names for the bot path. Add resolveTestWireType (internal/api/test_type.go),
which resolves a DTS template-type name, raw wire type, or hyphenated
CLI-display spelling to ProcessTest's wire type via dtsmap.AliasFold —
case-insensitive, idempotent on wire types. Its pokestop handling
deliberately diverges from resolveHookType: invasion/lure resolve to their
own token rather than collapsing to "pokestop", since ProcessTest's switch
(unlike !poracle-test's testdata.json bucket lookup) already dispatches
"invasion" directly and has no "lure" case at all — collapsing would either
be a no-op or a scope-creeping behavior change. Unknown types pass through
unchanged so ProcessTest's own error still fires. Also added the missing
"max-battle" hyphenated identity entry to dtsmap (mirroring the existing
"fort-update" entry) and updated the `type` field's OpenAPI doc string
(golden regenerated).
Fix 2: EnrichWebhook's synthetic "_editor" PVP display block gated on
`dtsAlias(webhookType).WebhookType == "pokemon"`, which covers
monster/monsterNoIv but misses monsterChanged (WebhookType is the derived
"monster_changed" spelling) even though its enrichment is a pokemon spawn
and the live !poracle-test path always computes this block. Gate on the
alias-authoritative result.templateType instead, so all three pokemon-family
template types compute the block consistently.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat: testable derived DTS types + unified enrichment + DTS-name-addressed test data
Mirror stardust (type 3) as an amount-based quest reward: min amount stored in the Reward column. Covers matcher, enrichment (fields, icon, rewardString), bot command grammar (pokecoins:N / bare pokecoins / everything / remove), slash option, NLP keyword, summary grouping, rowtext, DTS fields, i18n labels, docs, and a poracle-test scenario.
The pokecoins feature was branched from main, which predates the shared
validRewardTypes guard added on develop. Both the v1
(/api/tracking/quest/{id}) and v2 (/api/v2/humans/{id}/tracking/quest)
handlers gate on that map, so reward_type 8 was rejected (400/422): a
pokecoins rule could be created by the bot but not the API, and an
existing bot-created rule aborted API bulk saves on the first invalid row.
- add 8 to validRewardTypes (fixes both v1 and v2)
- document pokecoins in the v2 reward_type / reward field docs
- extend the v2 accept-all test + add a reward=amount round-trip test
- regenerate the OpenAPI golden
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gamelocale already ships quest_reward_8 ("PokéCoin"), which the i18n
bundle loads under the same key. The embedded en.json override only
duplicated it (as "Pokécoins"), so remove it and rely on gamelocale like
every other quest_reward_* label (stardust, candy, mega energy). English
now renders "<amount> PokéCoin" from gamelocale.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ported PoracleJS quest templates reference quest_task / quest_reward /
quest_conditions, but the processor only exposes the translated values as
questString / rewardString / conditionString, so {{quest_task}} et al.
resolved to nothing. The value was always computed — this was an alias
gap, not a missing field.
Add the three snake_case aliases to the quest alias table. Aliases resolve
ahead of the raw webhook layer, so the translated objective wins over any
scanner-supplied quest_task (Golbat sends `title`; MAD's quest_task is
obsolete). Documented in DTS.md; covered by a LayeredView alias test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(quest): add pokecoins reward tracking (type 8)
fix(dts): restore legacy PoracleJS quest field aliases
translateMonsterName suppressed any form whose translated name was
"Normal"/"Unset"/"" regardless of the form value. So an explicitly-tracked
Normal form (e.g. Rattata form 45, stored as a non-zero value) rendered
identically to the "any form" tracking (form 0) and to a second Normal
row — the user saw duplicate-looking "Rattata" rows with no way to tell
them apart.
Only form 0 ("any form") should drop a default Normal/Unset label. An
explicit form (form != 0) now keeps its name, including "Normal", so
distinct form trackings are distinguishable. Alola (form 46) was already
shown because "Alola" isn't a Normal-ish name.
Covered by a table-driven translateMonsterName test (normal/named/any).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
TestPoracleTest_DTSNameLoadsSameEntryAsWireType loads the same testdata entry twice (via "monster" and "pokemon" aliases) and compared the two dispatched payloads byte-for-byte. PoracleTestCommand freshens disappear_time from time.Now() at each dispatch, so when the two loads straddled a one-second boundary the payloads differed by 1s and the test failed — intermittently, on ~1% of CI runs. Normalize the freshened timestamp fields (disappear_time / start / end) out of both payloads before comparing, so the test proves "same entry" deterministically. Added a direct normalizeTestPayload test that encodes the exact 1-second-delta failure and guards against masking real diffs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(rowtext): show explicitly-tracked Normal form in !tracked
… from config
!poracle-test weatherchange showed no changed pokemon. The bundled and
operator weatherchange templates iterate {{#each activePokemons}}, but
WeatherTranslate only populates the activePokemons key when
[weather] show_altered_pokemon_static_map is set. enrichWeatherChange
hardcoded that flag false, so the test render never matched production
(where the flag is on) and the affected-pokemon list rendered as the
"could have altered the reported stats" fallback branch instead.
Read the flag from ps.cfg.Weather (nil-safe), exactly like the live
consumeWeatherChanges path, so !poracle-test faithfully reproduces the
live alert. The nil guard preserves the flag-off default for the
enrich-parity test harness (which leaves ps.cfg nil).
Tests: activePokemons is populated when the flag is on (was the failing
repro) and stays absent under a nil cfg (enrichedActivePokemons still
carries the data — no panic).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up to the show_altered_pokemon_static_map fix: with that flag on,
enricher.Weather returns no base tile — it defers to the per-user tile
that WeatherTranslate builds with active-pokemon markers. But
enrichWeatherChange discarded WeatherTranslate's pending (perLang, _ =
...), so once the flag read true the weather-change tile vanished from
the test render entirely.
Capture the per-user pending and prefer it over the (now-nil) base
pending, mirroring the live consumeWeatherChanges selection ("use
per-user tile if available, otherwise base tile").
Test: build a real staticmap.Resolver (tileservercache, an RFC 6761
.test URL so workers fail DNS instantly with no egress) and assert the
returned tilePending is non-nil with the flag both on (per-user tile)
and off (base tile). Reintroducing the discard fails the flag-on arm.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…h types map
POST /api/dts/enrich {type:"showcase"} returned 500 "unsupported webhook
type: showcase" while GET /api/dts/testdata exposed showcase in both the
types map (webhookType/templateType showcase, non-derived) and the
?dtsType=showcase bucket. showcase is a real, distinct DTS template type
(leaderboard + featured focus) with its own field set, fallback
template, and live handlers (ProcessShowcase / processTestShowcase) — but
the unified enrichForType dispatch that backs /api/dts/enrich never got a
showcase case, so the enrich side and the testdata/types side disagreed.
Add enrichShowcase (parses webhook.ShowcaseWebhook, enriches via
enricher.Invasion + InvasionTranslate over the rankings +
ShowcaseFocusTranslate, templateType "showcase") and wire it into
enrichForType's non-derived switch. Refactor processTestShowcase onto the
same enrichShowcase + renderJobFromEnrich core so the editor-enrich and
live-test paths share one implementation (the third copy this dispatch
was meant to eliminate) — the enqueued RenderJob still carries AlertType
"incident" and TemplateType "showcase", unchanged.
Tests: enrichForType("showcase") and EnrichWebhook("showcase") now
enrich (was 500); processTestShowcase still enqueues incident/showcase
with the leaderboard data in per-language enrichment.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…time test(poracletest): de-flake DTSName payload comparison
fix(dts): showcase enrich (#172) + weatherchange enrich follow-ups
Adds a `derivedDtsTypes` boolean to the GET /health capabilities map, alongside the existing flags (buttons, snapshots, autocreate, tomlDts, buttonResponseObject). It is hardcoded true here because this binary carries the enhanced DTS enricher — the one that returns the DTS-type `types` map from GET /api/dts/testdata, honours ?dtsType=<name>, and accepts DTS type names (including derived types: monsterChanged, incident, questSummary, weatherchange, rsvpChanges — and showcase) at POST /api/dts/enrich. Those pieces ship together, so a single flag represents the whole feature: "flag present and true" is exactly equivalent to "enricher available". Non-breaking — editors that don't see the key fall back to structural detection (presence of the `types` map); the flag just lets them detect support from the unauthenticated /health response and skip an extra round-trip. No other endpoint or response shape changes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(health): add derivedDtsTypes capability flag
…dow the fallback Saving an override of a platform-agnostic fallback (the per-command help templates, loaded from fallbacks/dts/help/*.json with platform="") produced a DUPLICATE in the editor's template list: the readonly fallback (help, fort, "") plus the user's copy (help, fort, "discord"). Root cause: POST /api/dts/templates rejected platform="" (400 "missing required fields"), forcing the editor to save help with a concrete platform. That platform-specific entry has a different entryKey than the agnostic fallback (entryKey includes platform), so the dedup — which drops a readonly fallback only when a user entry shares its (type, platform) surface — never dropped it. Both surfaced. Fix (server half of the coordinated fix): allow platform="" on save for platform-agnostic types via dts.IsPlatformAgnosticType (help today). A saved (help, fort, "") override then shares the fallback's key and cleanly shadows it — one entry, not two. Non-agnostic types (monster, raid, …) still require a concrete platform. Also tidy entryFilename so an empty platform yields "help-fort.json" rather than "help-fort-.json". The editor half (poracle-embed-visualizer) must stop coercing empty platform to "discord" (useDts.js: `e.platform || 'discord'`) for agnostic types so it sends platform="". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Companion to the server fix in this PR: the editor half (stop coercing empty platform to discord for help; show agnostic entries in every platform tab; save help with platform=""; surface readonly fallbacks in the list with a badge). Notes that help is the only agnostic type. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(dts): allow platform-agnostic (help) overrides so they shadow the fallback
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Long-lived release PR for the next development cycle (successor to #121, which shipped 5.1.0). Version on this branch: 5.2.0.
Accumulated so far
OpenAPI-documented API + strict /api/v2 (
huma-api-migration)/apigroup: live OpenAPI 3.1 spec atGET /openapi.json, interactive docs atGET /docs, RFC 9457problem+jsonerrors across the documented surface./api/v2: 11 tracking types (including the new incident type) on human-scoped paths/api/v2/humans/{id}/tracking/{type}with GET/POST/PUT/DELETE + bulk delete + full snapshot; discrete typed humans/profiles/locations/roles actions; newPUT …/locations/{label}; omit-to-wildcard requests with null-at-wildcard responses;pvp_ranking_evolutionexposed.docs/v1-to-v2-migration-guide.md, design indocs/v2-api-design.md, RFC RFC: PoracleNG v2 API — clean, documented, OpenAPI-first (feedback wanted) #138.v2 mutes API (#146)
GET/POST /api/v2/humans/{id}/mutesandDELETE …/mutes[?scope=&value=]expose the in-memory alert mutes (previously bot-command/button-only) with bot-parity validation; the v2 full snapshot now carries amutesarray. Mutes stay volatile by design (cleared on restart, documented on the wire). Design:docs/superpowers/specs/2026-06-11-mute-api-design.md.Bug fixes
!track charizard … mega(and any mega evolution-direct rule) never fired: the PVPevoDatapath was gated to base forms only, dropping the Mega entry before it reached the matcher. Removing that guard and tagging each entry with its evolution lets the PVP mega-evolution matching (mega / mega:x / mega:y) #136 discriminator route mega entries correctly. Non-mega evolution tracking unchanged.Dependencies & housekeeping
go get -u ./...): sonic, validator, golang/geo, prometheus/common, quic-go, and the golang.org/x stack.Every merge to this branch passed the full local gate (build / vet / test / golangci-lint).
🤖 Generated with Claude Code