{
  "generated_at": "2026-11-02T02:07:53.51030884Z",
  "enabled": true,
  "roster_source": "default",
  "writes_enabled": false,
  "writes_disabled_reason": "writes are disabled: set dashboard.allow_writes: true in config.yml to allow editing the agent roster from the dashboard",
  "roster_file": "",
  "agents": [
    {
      "id": "wayfarer",
      "name": "Wayfarer",
      "role": "Jack-of-all-trades",
      "responsibilities": "Everything without a dedicated specialist: general features, fixes, refactors, docs, tooling, and any task that spans several specialties at once. The road decides your work; you are ready for all of it.",
      "fallback": true,
      "issues": 939,
      "succeeded": 791,
      "failed": 28,
      "main_attempts": 2996,
      "tokens_in": 9486373119,
      "tokens_out": 41825710,
      "cost_usd": 3738.3695613000027,
      "last_active": "2026-11-01T15:13:31.48987891Z",
      "memory": [
        "For an r3-platform \"admin global on/off switch\" feature request, check whether the switch needs to be readable by an *unauthenticated* visitor (e.g. a public landing-page banner) before assuming the existing tenant-scoped FeatureFlagsContext suffices — it only fetches `/settings/feature-flags/tenant/:tenantId`, which needs a resolved tenant and silently no-ops for anonymous users.",
        "On a release issue blocked on an owner secret or vendor action, always re-check the merge state of every sibling cross-repo PR the status docs cite before escalating — one that merged after the docs were last written turns the escalation into a real deliverable (correcting the now-stale readiness claims) instead of an empty re-confirmation.",
        "When a frontend module's page needs an effect that only calls the API once on mount but also uses `t()` for its error strings, don't put `t` in a `useCallback`/`useEffect` dependency array — react-i18next's `t` is not a stable reference across renders in test mocks (and can vary in production too), so depending on it turns a mount-only fetch into a fetch-on-every-render loop; make the effect depend on `[]` instead and suppress exhaustive-deps explicitly.",
        "For an r3-platform \"app-wide maintenance gate\" ask, the correct implementation is a single new gate component (mirroring BackendUnavailableGate) wrapped around RootLayout's `\u003cOutlet/\u003e` inside FeatureFlagsProvider/PlatformAuthProvider, using `useFeatureFlags().isEnabled(key)` plus `rolesSatisfyRequiredRoles(user.roles, ['system-admin'])` from `@r3/common` — no new backend wiring needed when the flag and its public status endpoint already exist from a sibling issue.",
        "When an r3-platform admin-page-swap issue depends on an unmerged sibling app-shell PR, branch the new work off that sibling PR's branch (not develop) and open the new PR with that branch as its base, since the swap assumes the shell's already-ported provider tree.",
        "For r3-platform issue #3941's sweep retries, re-checking r3-blog PR #166 (and its prerequisite PR #164) via `gh pr view --repo michelroberge/r3-blog` is the fast, correct re-confirmation path each time.",
        "For r3-platform issue #3941's sweep retries, re-checking r3-blog PR #166 (and prerequisite PR #164) via `gh pr view --repo michelroberge/r3-blog` remains the fast, correct re-confirmation path — both stayed open/mergeable/clean again on this pass.",
        "For r3-platform issue #3941's repeated sweep retries, the fix stays entirely in r3-blog PRs #166/#164, both of which remain open/mergeable/clean on every re-check — the cross-repo gap-scan dedup pattern continues unchanged.",
        "In r3-platform, when a reported \"menu item/route/card never shows up although direct navigation works\" bug involves a `FrontendModuleDefinition`, check whether its `entry.id` has a backend-declared `\u003cid\u003e.enabled` feature flag before assuming a rendering/registration-timing bug — `getRegisteredMenuItems`'s per-module flag gate fails closed (hides everything) for any id with no such flag ever declared, and this generalizes to any module (built-in or out-of-process) whose id lacks that declaration.",
        "For r3-platform issue #3989 (keycloak/refactor bundle), the `keycloak/theme/fermierdefamille/login/resources/css/login.css` Sonar findings (S7924 contrast, S4666 duplicate selector) were fixed directly in that standalone theme file — it sits outside apps/libs/templates so no propagation step was needed.",
        "For r3-platform issue #3869 (five-module submit-and-release), the blocked state (missing `ONPREM_PACKAGE_PUBLISH_TOKEN` + catalog host credential + human vendor review) is stable and expected to recur on sweep retries exactly like the other cross-repo/secret-blocked release issues in this fleet — re-verify fresh each time and re-confirm, never attempt a workaround.",
        "For r3-platform issue #3956, the deferred GlobalAuthGuard/ThrottlerModule audit on r3-blog found only two gaps (AppController health, LocalOidcController) with everything else already correctly annotated, and the full fix (PR michelroberge/r3-blog#169) required zero r3-platform code changes — live-verified via a disposable Postgres boot (200/401/429).",
        "For r3-platform issue #3956, the sweep retry pattern continues — PR michelroberge/r3-blog#169 stays open/mergeable/clean on each re-check, and the correct response remains a cheap PR-state re-check plus a short re-confirmation comment, never rework.",
        "For r3-platform issue #3956, sweep retries keep landing on the same stable state — PR michelroberge/r3-blog#169 open/mergeable/clean — and the correct response each time is a cheap re-check plus a short re-confirmation comment, no rework.",
        "For r3-platform issue #3956, sweep retries continue to land on the identical stable state — PR michelroberge/r3-blog#169 open/mergeable/clean, zero r3-platform code changes — and the correct response is a cheap re-check plus a short re-confirmation comment every time.",
        "For r3-platform issue #3956, sweep retries keep landing on the identical stable state — PR michelroberge/r3-blog#169 open/mergeable/clean, zero r3-platform code to change — and the correct response is a cheap re-check plus a short re-confirmation comment every time.",
        "On a release-blocked gap-scan issue, ship the doc correction *and* the strongest proof the blocker still permits, then split the blocked step into its own child issue — that converts a repeat escalation into two real deliverables.",
        "For r3-platform issue #4012, the prerequisite state is identical to #3869/#3928 — ONPREM_PACKAGE_PUBLISH_TOKEN and LICENSE_CATALOG_CREDENTIAL both absent, both license-server routes 401 live, no `brainfolio` entry in module-identity-ledger.json — and the threat-model/partner-review docs already carry #3957's corrected language, needing no further edit since no release occurred since.",
        "For r3-platform's \".r3/ + @r3/scripts\" bootstrap issues on apps created before `.r3/` existed, check whether `@r3/scripts` even existed as a package at the app's pinned `@r3/*` version before assuming an exact-version match is possible — it shipped later than many 1.x app pins, and `r3 doctor` shipped even later (2.x only), so \"stay on 1.x\" and \"run r3 doctor\" can be mutually exclusive acceptance criteria on the same issue.",
        "Issue #4017 (r3-obnl .r3/ merge base + @r3/scripts) is another instance of the cross-repo gap-scan dedup pattern — the fix lives entirely in r3-obnl PR #107 (open/mergeable/clean as of this check), and sweep retries should be resolved with a cheap PR-state re-check, no rework, no new report comment when a complete one already exists.",
        "Issue #4017's sweep retry keeps landing on the identical stable state — r3-obnl PR #107 open/mergeable/clean, zero r3-platform code to change — resolved each time with a cheap PR-state re-check and short re-confirmation comment, no rework.",
        "Issue #4017's sweep retry has recurred at least 4 times with identical stable state (r3-obnl PR #107 open/mergeable/clean, commits e47354a+6772463 unchanged) — resolve each retry with a cheap `gh pr view --repo` check and a short re-confirmation comment, never rework.",
        "Issue #4017's sweep retry has now recurred at least 5 times against the identical stable state (r3-obnl PR #107 open/mergeable/clean, same 2 commits e47354a+6772463) — resolve each with a cheap PR-state re-check and short re-confirmation comment, never rework.",
        "For r3-platform's cross-repo gap-scan dedup pattern, a fast re-check is `gh pr view \u003cN\u003e --repo \u003cowner/repo\u003e --json number,state,mergeable,mergeStateStatus,commits` plus `git status` on the home repo — both in one command batch — before writing any re-confirmation comment.",
        "For r3-platform's docker/refactor Sonar bundle issues (docker:S7031 \"merge consecutive RUN\"), verify by actually running `docker build` (and inspecting the resulting container) rather than relying on `docker build --check`, since buildkit's built-in check set doesn't include this rule and reports \"no warnings\" both before and after the fix.",
        "Before decomposing an epic, search for existing children (`gh issue list --search \"\u003cN\u003e in:body\"`) and verify they carry a literal `Parent: #N` line — unregistered-but-complete children are a common cause of an epic being re-attempted, and the correct fix is registering them rather than creating duplicates.",
        "When an epic's scope note says a box \"likely needs a platform change\", verify it against the pinned platform checkout's actual source before decomposing — an already-available upstream parameter can move that box off the critical path and change the whole dependency chain.",
        "For r3-platform app bootstrap issues (\"record .r3/ merge base\"), always check whether the app's exact pinned @r3/* version has a reachable git commit before assuming a tag or commit exists — registry-published versions can skip git history entirely (squashed/retried publishes), requiring a same-day nearest-commit substitute chosen via publish-timestamp cross-reference.",
        "For an r3-platform FORCE-RLS bug report naming specific admin endpoints, grep every sibling controller method sharing the same global/platform-scoped permission convention with no `@TenantGate` on the same RLS table — these recur as the identical bug and are usually confirmable as genuinely cross-tenant via the frontend admin page that lists \"all tenants\" and then mutates by id.",
        "A multi-PR plan inside one issue body is a decomposition signal, not a work order — but verify each PR's claims against the code first, since that is what turns a transcribed split into one with correct dependency ordering and named extension points.",
        "For network-disabled Docker sandboxes, reproduce resolver-timeout bugs directly against the real daemon (varying libc and nameserver reachability) rather than reasoning about them — the actual hang duration and exact errno text depend on musl-vs-glibc behavior that isn't obvious from documentation alone.",
        "For r3-platform's `templates/frontend`, which has no local `node_modules`, a temp tsconfig that keeps its existing `paths` map but rewrites every `node_modules`-relative entry to the repo-root hoisted `node_modules` gives a real, clean `tsc --noEmit` without any install step.",
        "When a prior report comment's described files and verification exactly match `git show --stat` on the branch's current commit, a quick re-confirmation comment plus the completion marker is sufficient — no need to re-run tsc/tests before closing the loop.",
        "For r3-obnl specifically, booting the real NestJS app (not just `migration:run`) requires Node 22+ (Node 18 hits `ERR_REQUIRE_ESM` on `@r3/backend`'s `jose` import) plus `nest build` (which still emits `dist/` despite the 4 pre-existing licensing-module type errors) and a `SESSION_SECRET` env var of at least 32 chars — once running, curling anonymous requests against both the newly-public and newly-protected routes is the fastest way to prove a GlobalAuthGuard rollout is correct.",
        "Issue #4083 (r3-obnl GlobalAuthGuard + fail-closed route.public adoption) is a stable cross-repo gap-scan dedup case — the fix is entirely in r3-obnl PR #114 (open/mergeable/clean), and sweep retries should be resolved with a cheap `gh pr view --repo michelroberge/r3-obnl` check plus a short re-confirmation comment, never rework.",
        "For r3-platform issue #4117, the #3330 zero-key fix for r3-home's crm-m365-integration-module was real but stuck as a local unpushed commit on a stale branch ~130 commits behind develop — re-applying the exact diff onto a fresh branch from current develop worked cleanly, and this time the branch was actually pushed and PR'd (https://forge.michel-roberge.com/michel/r3-home/pulls/694) instead of left local-only.",
        "r3-platform issue #4117's sweep retry is a stable cross-repo gap-scan dedup case — the fix is entirely in r3-home PR #694 (open/mergeable/clean), re-verified via the Forgejo API, and should be resolved with a cheap re-check plus re-confirmation on every retry, never rework.",
        "r3-platform issue #4117's sweep retry is now confirmed stable (r3-home PR #694 open/mergeable/unmerged, head c736a32) — resolve via cheap Forgejo API re-check plus re-confirmation comment, never rework.",
        "When a task asks for a new static-site/doc-tooling folder in a pnpm-workspace repo whose Docker builds do a whole-repo `COPY . .` + `pnpm install --frozen-lockfile`, keep that folder on its own `npm`-managed package.json/lockfile outside the pnpm workspace rather than adding it as a workspace member — that fully isolates its dependencies from every existing Docker build with zero workspace-config changes.",
        "r3-platform issue #4117's sweep retry remains stable indefinitely (r3-home PR #694 open/mergeable/unmerged, same head c736a32 across many checks) — this is the expected cross-repo gap-scan dedup pattern, not a sign of missing work.",
        "For sweep retries on cross-repo gap-scan issues, a one-command batch (git status + Forgejo API PR check) is enough to produce a fresh, accurate re-confirmation without rework.",
        "For a \"sibling module already fixed this exact pattern\" bug report, read the already-hardened sibling's implementation and spec test in full before touching the broken file — the fix is almost always a direct port with only the salt/env-var-name/error-message swapped.",
        "For r3-platform's menu-item feature-flag gate family (#3958/#4118), `grep -rl \"menuItems\" libs/platform-client/src/modules/*/modules/*frontend.module.tsx` is the complete, cheap way to enumerate every module exposed to the fail-closed `\u003cmoduleId\u003e.enabled` gate — as of this check only `messages` and `workflows` register menuItems, and `workflows.enabled` was already declared, so `messages.enabled` was the only remaining gap.",
        "Issue #4083's sweep retry remains stable indefinitely (r3-obnl PR #114 open/mergeable/clean, same head 537399c) — resolve each retry with a cheap PR-state re-check plus re-confirmation, never rework.",
        "For a \"port forward a host customization onto a newly-adopted @r3m/* package\" issue, always grep the installed package's own dist for the customization's distinctive flag/constant name first — it can already be fully implemented there, turning the task into live verification plus drift-exception cleanup rather than new code.",
        "When a prompt-building pure function (like buildAutofillPrompt) already has an established pattern of conditionally naming a data tag in its system sentence only when that data block is actually present, extending it for a new optional data block should follow the identical \"only mention the tag when the block exists\" rule so \"feature enabled but no data yet\" stays byte-identical to \"feature off.\"",
        "For r3-platform issue #4119, confirmed the gap is real on ai-refactor (e17727a80) but escalated as ARCHITECTURAL_BLOCKER since the fix needs ModelGatewayService/completeOnGateway, which exists only on ai-refactor — a branch exclusively worked via the owner's manual ai-harness/* sessions (all 20+ recent PRs into it, including sibling fixes #4091/#4092/#4107, are human-authored).",
        "For an \"ai-refactor\"-family deletion/removal issue, check whether the files named for deletion even exist on develop before assuming any part is actionable — a legacy-path removal gated on an unpublished gateway release can have zero footprint on the agent's own branch, not just a partial one.",
        "For r3-platform's `@r3/frontend` DataTable-integration props (like `savedViewKey`), verify the paired registration function is actually exported from a public subpath (check the package's `exports` map and the bundle's literal export statement) before relying on it, rather than trusting its `.d.ts` — if it's unreachable, render the underlying exported component (e.g. `SavedViewPicker`) directly via a generic prop like `toolbar` instead.",
        "When a prior session's full report already appears on the issue thread under the human account (per repo gotcha), re-confirming only requires a cheap git log/status + tsc check — never re-post the report or redo the implementation."
      ]
    },
    {
      "id": "runekeeper",
      "name": "Runekeeper",
      "role": "Database modeling specialist",
      "responsibilities": "Data modeling and storage: schemas, migrations, entities and relations, indexes, query shape and performance, and the integrity rules that keep stored data trustworthy. You guard the shape of everything the platform remembers.",
      "labels": [
        "database",
        "db"
      ],
      "keywords": [
        "database",
        "schema",
        "migration",
        "sql",
        "entity",
        "index",
        "typeorm",
        "relation",
        "data model",
        "dolt",
        "postgres",
        "jsonb"
      ],
      "fallback": false,
      "issues": 613,
      "succeeded": 490,
      "failed": 12,
      "main_attempts": 2309,
      "tokens_in": 9278920516,
      "tokens_out": 35190741,
      "cost_usd": 3490.812768949996,
      "last_active": "2026-11-01T15:13:31.595062062Z",
      "memory": [
        "When adding a retention/purge job for a table, pair an age-based rule keyed on an existing `(tenantId, createdAt)` index with a keep-newest-N rule via `row_number() OVER (PARTITION BY \u003cgroup\u003e, \u003cowner\u003e)` — partitioning by the owner as well as the group is what stops one user's churn from deleting another's newest row that a \"latest\" query still needs — and never rely on `Repository.query()`'s return shape to count affected rows (it yields a `[rows, count]`-shaped value for DML); use a delete query builder's `affected` instead.",
        "Before implementing or decomposing a parent issue, replay the controller's own `parentPattern`/`depPattern`/`refListPattern` regexes from github-agent's main.go against the live child bodies — existing, well-written children can be wholly invisible to the orchestrator over one keyword, and the same replay proves cross-repo refs in a dep line don't become phantom local dependencies.",
        "When a committed-but-unmerged fix sits on a branch whose base has since moved, merging the base in and re-running the gates is real verification work, not bookkeeping — conflicts in a module manifest's invariants list are where a stale \"ours\" silently reverts a newer, truer statement from the base.",
        "A hard-coded `roots`/`testMatch` module list in a monorepo's jest config silently excludes specs in newer module folders, so always diff the runner's discovered-suite count against a filesystem `find` for spec files before trusting any \"N tests pass\" baseline.",
        "When a published @r3m/* package's own `r3.module.json` `dependencies` entry still names a sibling by its stale pre-migration directory name (e.g. \"module-registry-module\" instead of \"module-registry\"), it's harmless for the packaged-module boot path (that resolver reads the packed `package.json`'s `@r3m/*` dependency keys, which `r3 pack` already resolved correctly at build time) — the real risk is every *other* still-vendored `apps/modules/*/module.json` that names the migrated module by its old directory name in its own `dependencies` array, since `generate-backend-module-imports.mjs`'s fallback silently keeps that stale string and the boot gate then skips the whole dependent module with no compile-time signal; grep every sibling module.json for the old name (not just TS import specifiers) before considering a module migration done.",
        "When an RLS-enablement epic cites a \"audit every table for tenantId\" step, run the audit first and exclude generated re-export shim directories — the schema half is often already clean, which moves the real work to write-time context (runAsTenant wrapping of background writers) and makes the DB-role change, not the feature flag, the arming step to sequence first.",
        "r3-platform's published 1.x `@r3/backend` package has a genuine migration-ordering gap — `AddReplyToToEmailTemplates1753056000000` runs before any migration creating `email_templates` (`CreateEmailTemplatesTable` never shipped in a published 1.x release) — host apps hit this on a fresh `migration:run` and it isn't fixable from the host side.",
        "For an r3-platform \"backport a migration to an old major's published line\" issue, first check whether the publish script bases its next version on the registry's overall max across every major (not the target line's own latest) and whether it publishes without an explicit `--tag` — if so, a parallel 1.x patch risks silently moving npm's `latest` dist-tag backward onto the lower version, which is reason enough to resolve via documentation (freeze + workaround) instead of publishing, especially when every known consumer of the old line is already tracked to upgrade off it.",
        "When porting safeguards from an r3-platform template module into a permanently host-owned fork, diff the template's current service file directly against the fork's and apply each safeguard as an independent hunk — this surfaces exactly which pieces (e.g. a `hasHandler`-gated license-growth check, a Communication-Center-with-fallback email path, an enumeration-safe early-return) compose cleanly with the fork's own divergent logic (e.g. an extra domain entity the template doesn't have) without needing to touch it.",
        "When an epic claims a new auth mode, check whether the credential store's shape can even hold it — a single `encryptedSecret` text column cannot carry a principal-plus-binary-keytab pair without either base64-into-one-slot or a new column, and that choice is the data-model decision the child issue must own.",
        "When an epic bundles several \"publish a page\" deliverables (security posture, benchmarks, release notes), make the docs-site/publishing-surface child the single dep-free root they all chain on — otherwise each sibling independently invents its own publishing mechanism and information architecture.",
        "For a nullable-varchar `organizationId`→`tenantId` rename on a published-module adoption, a straight idempotent `RENAME COLUMN` (no backfill/NOT NULL step) is provably correct and reversible via a disposable-Postgres round-trip test (`up()` twice, `down()` twice) seeded with pre-migration data, which is far cheaper than replaying the full historical migration chain.",
        "For agiler3's contact-us migration, the straight nullable-varchar `organizationId`→`tenantId` rename plus adopting `@r3m/contact-us` closed the client-supplied org-routing security hole simply by the package's `ContactUsDto` having no tenant field at all, resolved server-side via `@CurrentTenant()` instead.",
        "For r3-platform issue #4058, verification was fast because each of the 4 referenced PRs' commit messages and diffs were self-documenting enough (docstrings explaining the numeric-trace scorer's exact semantics, migration names matching the issue's own text) to confirm correctness without re-reading full implementations line by line.",
        "When re-confirming a prior report whose target branch tip has advanced since it was written, re-check the specific artifacts a later commit could disturb — migration registration ordering and a new table's constraint/RLS statements — rather than just re-verifying the original PR SHAs, since matching SHAs say nothing about what landed after them.",
        "For a NestJS-major-version package bump, verify Node's `require(esm)` support (stable on Node 22.12+/24) before assuming CJS-based dev/migration/seed entrypoints need ESM conversion — actually run them, don't just compile.",
        "When extracting a port from existing code, make the adapter's \"limitation\" an explicit per-context `restriction()` hook rather than a missing capability, and prove delegation with both byte-pins and an A/B run against the bare helper on identical recording fakes — the pin catches a rewritten statement, only the A/B catches a dropped or reordered argument.",
        "When re-confirming a migration-bearing deliverable, the fastest decisive data-model check is the unique index that encodes the feature's stated cardinality rule (e.g. one-row-per-run-and-user) — if that constraint lives in the schema rather than in service code, the integrity claim holds regardless of what changed above it.",
        "For r3-etl issue #642, checking a live \"non-lowercase model table\" risk required querying `etl_definitions.spec-\u003e\u003e'table'`/`targetTable` directly via `scripts/db-query.js --env .env` against the dev DB (10.0.0.83) — the right technique when a bug-fix issue's acceptance criteria ask to check production-shaped data before changing which physical table a write targets.",
        "For r3-platform issue #4058's sweep retry, when the target branch's tip is unchanged since the prior pass, confirming tip-unmoved + SHA-ancestry alone is sufficient — no need to re-derive the same drift-exposed schema/migration checks against an identical state.",
        "When a sweep rejects a report citing the very evidence that proves it correct (e.g. \"only tracking files changed\" on a cross-branch deliverable), quote that evidence back as corroboration rather than arguing against the rejection.",
        "When adding a column plus constraint to a table whose schema diff is already non-empty, capture the baseline diff from a database built with only the older migrations and assert the new state matches that — asserting \"diff is empty\" misreports accepted divergences as failures, and asserting nothing hides a constraint synchronize will silently drop.",
        "When an epic's remaining item \"waits for\" a sibling issue only as prose in a comment, converting that into a child issue with an explicit `Depends on #N` line is real work — the picker cannot honour prose, so the item can otherwise be selected prematurely onto a base that lacks its prerequisite column.",
        "When extracting a port, check whether any decision is made by *object identity* (pool/handle comparison) — a tracing or proxy wrapper layer will silently flip it once the adapter holds the raw handle, so the port needs an explicit unwrap and the adapter must take over the wrapping.",
        "When an issue states a belief about which datastore some code touches (\"the writers hit the control DB\"), verify it against the code before building anything that depends on it — a port/ban allowlist written on a false premise legitimises exactly the coupling it was meant to forbid, and the correction usually splits the work cleanly into \"route this one now\" and \"file that one as a tracked pending entry\".",
        "For r3-etl's ETL profiling SQL builder, type-based aggregate-availability decisions (what min()/max()/histogram to emit) are made once from `information_schema.columns.data_type` discovered up front, never by catching a runtime SQL error — the same pattern already used for the numeric/histogram vs. money distinction extends cleanly to a min/max-availability distinction for uuid/json/jsonb/xml/point/ARRAY.",
        "When writing a port's conformance suite, keep the cases as plain data that assert by throwing and bind them to the runner through a structural harness — that keeps the suite inside the build's real type gate, free of a test-framework dependency, and lets every capability-or-restriction skip carry its own reported reason instead of passing vacuously.",
        "When a port+adapter epic's \"add the second engine\" phase names a bulk/native-transport facet, check whether that facet's input format is the first engine's wire encoding — a signature like `copyRows(table, columns, lines)` that documents \"already-formatted lines\" is an undeclared engine coupling, and settling it is a port change that must precede the new adapter rather than be discovered inside it.",
        "For r3-platform's mcp-server module, a data skill's declared `responseSchema` columns (McpResultColumn) are the natural place to add a per-column policy flag (like `sensitive`) since both the AI-proposal validator (mcp-skill-generation.ts) and the save-path validator (mcp-skill.validator.ts) independently enforce the same column-key allowlist and must be updated together.",
        "When retiring a discriminator value, prefer keeping the column's loose type (plain text, no enum/CHECK) and instead harden the three runtime paths that read it — the dispatch default, every allow-list, and any unchecked cast in an import/deserialization path — since a constraint would hard-fail legacy environments while the cast is where unrunnable rows actually get written.",
        "For agiler3 issue #881, the `ai-agent-module` template drift wasn't just version skew — it had adopted a full model-gateway + MCP tool-catalog runtime architecture (#3964 upstream) replacing direct SDK calls, while the host's vendored copy carried two independent, template-absent features (a full \"bead\" data model/API/UI, and a sandboxed bash-tool + MCP bearer-token-auth customization) that needed separate sub-issues (#903–#906) rather than one mechanical port.",
        "When a decomposition's own report comment is already posted but the session ended without the completion marker, re-verify every child issue's existence, Parent/Depends-on lines, and git cleanliness, then post a short re-confirmation and emit the marker — no new issues or code needed.",
        "When an async generator feeds `Readable.from(...).pipe(dest)`, a throw inside it becomes an unhandled rejection in Node's stream internals and the destination just *ends* — so a streamed request body silently looks complete to the far side; catch inside the generator, `destroy(dest, cause)` to force the receiver to abort, swallow the deliberate `error` emit on the destination, and rethrow the cause after the transport call settles.",
        "When a host-module-package migration finds the published npm package lags the platform's git checkout (confirm via `npm view \u003cpkg\u003e versions`/dist-tags plus a 1:1 file-list diff of installed `dist` vs the vendored `src`), treat the issue's own drift triage as unverified until re-checked against what's actually installable — a security-relevant customization (like a skill-chat userId-impersonation guard) can be missing from the published version even though the platform's current template has since fixed it independently.",
        "When migrating an app-local module to its published `@r3m/*` package replacement, check whether the installed platform SDK actually registers the new architecture's QueryBus handlers (via `hasHandler`) before assuming any behavior change — if it doesn't, the \"architecture swap\" issue is often purely structural with zero functional risk.",
        "For agiler3 issue #904, re-confirming a prior complete report (ai-agent-module → @r3m/ai-agent swap) only required checking the vendored dir's absence, package.json/tsconfig entries, the commit's diff stat/message, and the two sibling deferral issues (#905/#906) — all matched, no rework needed.",
        "For r3-etl's MCP skill surface, the real permission boundary differs by transport — the in-app chat path enforces `skill.requiredPermissions` via `isOfferedInChat`, but the raw external `POST /api/mcp-server/mcp/:tenantId` JSON-RPC `tools/call` path (`McpServerService.callTool`) in `@r3/backend` does not, so any issue scoped to fixing only the in-app caller (like r3-etl #618) leaves the external transport's \"token-can-reach-every-enabled-skill\" gap open.",
        "When a published platform package's own NestJS module exports entity classes but not the services wrapping them, borrowing the entity's TypeORM repository directly (mirroring the host's own existing precedent for a sibling package) is usually sufficient for simple CRUD/lookup needs, but any orchestration that drives a real side effect (spawning a process, managing a connection pool) has no such substitute and must move to whichever layer still has a legitimate public route to the other package's REST/service surface — usually the frontend, if the orchestration was originally reachable from a user action.",
        "For agiler3 issue #905, a prior session's report was accurate and complete (bead feature ported to the new app-owned ai-agent-beads module) but ended without the completion marker — re-confirming just needed tsc --noEmit on both apps plus a directory/file existence check, no re-implementation.",
        "For a documentation issue with no existing canonical doc location, check sibling vendored modules' own CHANGELOG.md convention (one per `apps/modules/\u003cname\u003e/`) before inventing a new location — it's often already the house pattern.",
        "For r3-platform's ai-skills module, a per-field privacy flag (like `sensitive`) that controls storage must be applied identically to both saved-record and unsaved-form feedback paths, and any client hook that previously withheld data for forms-only (e.g. the frontend never sending a form's edited value) has to be updated too, or the backend change is a no-op for that surface.",
        "When a published `@r3m/*` package's compiled output lags the current r3-platform template checkout for specific exports (not just whole features), diff the installed package's own `dist/index.d.ts` against the template's `index.ts` barrel before assuming any given symbol is importable — the missing pieces are often small, self-contained UI/utility files with no backend dependency, cheaply ported forward as host-owned code under the package's already-exported primitives (hooks/components) rather than requiring a drop or an upstream wait.",
        "When a stats endpoint joins a run-count aggregate with a per-user-decision aggregate, the bounded-rate fix is usually to add an explicit decision-count denominator field (not redefine the run count), and any \"since\" asymmetry between the two aggregates' filter columns should be resolved by picking one column (usually the parent entity's creation time) and reaching it from the other table via a subquery rather than a join, to preserve existing no-join performance guarantees.",
        "For documentation-only issues, \"iteration ended without a completion marker\" sweep retries are frequently just a lost marker on already-complete, already-committed, already-reported work — verify the existing commit and comment before writing anything new.",
        "For r3-platform's ai-skills module, extending a corrected stats-aggregation SQL builder (like #4100's `decisionCountsSql`) with one more GROUP BY dimension (a confidence-bucket CASE expression) as a sibling exported function is the safe way to add a new read pattern without touching the original contract/REST endpoint at all, keeping an unrelated bug-fix's shipped behavior fully isolated from new work built on top of it.",
        "When a feedback-driven \"demote a feature based on recent outcomes\" mechanism needs a trailing-window stat per key, computing it live via a `ROW_NUMBER() OVER (PARTITION BY key ORDER BY timestamp DESC) \u003c= window` query against the existing feedback table is simpler and equally correct compared to a scheduled-recompute table, when the query only runs for the narrow subset of keys actually eligible (here, fields already ruled auto-apply) rather than tenant-wide on every tick.",
        "For an r3-platform module (`@r3m/*`) version-bump+republish acceptance criterion, run `publish-module.mjs` directly instead of assuming it needs the libs-publish Node-24/host procedure — its build/pack/dry-run steps alone double as a real compile check for template code that has no local tsconfig, and the registry-publish step can legitimately succeed even when the token-gated license-server submission can't.",
        "For r3-platform's `@r3m/*` module publish-gap issues (template exports shipped but package never version-bumped/published), the fix is purely mechanical — bump `package.json`+`module.json` in lockstep with a CHANGELOG entry, dry-run `publish-module.mjs` to confirm the tarball's `frontend/dist/index.d.ts` carries the new exports, then publish for real and re-verify via a fresh `npm pack` from the registry; apps consuming the module via `workspace:*` need no `update:app` run at all.",
        "For an r3-platform agent-harness schema issue that defers \"the reporting query\" to a sibling, the deciding factor for jsonb-GIN-index vs. a normalised child table is whether the sibling's query needs to GROUP BY/count across entries (table wins) or just test containment (GIN suffices) — check the sibling issue's own acceptance text before picking.",
        "When a prior report comment's bullet list names exact migration numbers and file names, a `git show --stat` on the matching commit is enough to re-confirm it without re-reading the implementation."
      ]
    },
    {
      "id": "herald",
      "name": "Herald",
      "role": "CQRS \u0026 event patterns specialist",
      "responsibilities": "Command/query separation and event-driven architecture: command and query bus contracts, handlers, domain events and subscribers, sagas, projections, and the messaging boundaries between modules. You keep commands, queries, and events clean, explicit, and decoupled.",
      "labels": [
        "cqrs",
        "events"
      ],
      "keywords": [
        "cqrs",
        "command bus",
        "query bus",
        "event",
        "handler",
        "saga",
        "projection",
        "subscriber",
        "dispatch",
        "messaging",
        "domain event"
      ],
      "fallback": false,
      "issues": 297,
      "succeeded": 237,
      "failed": 6,
      "main_attempts": 1110,
      "tokens_in": 4031232161,
      "tokens_out": 17183677,
      "cost_usd": 1532.306626249999,
      "last_active": "2026-11-01T15:13:31.703696596Z",
      "memory": [
        "When a Sonar bundle finding's two flagged \"duplicate throw site\" lines land in two now-deleted sibling files (e.g. approval-node.service.ts and human-node.service.ts), check whether a prior consolidation commit (git log --diff-filter=D) merged both into one successor file/function — both findings often collapse into a single fix there.",
        "When a fix requires a literal backslash-u-escape sequence (e.g. `\\u003c` inside a `String.raw` template) to land verbatim in a file, Edit/Write tool calls can silently collapse it into the real unicode character — write that exact content via a Python/shell heredoc instead, and verify with a test that exercises the escaped output.",
        "For a Sonar S5843 regex-complexity finding on a pattern with two near-identical alternation branches differing only by an optional extra delimiter character (e.g. double-brace vs triple-brace placeholder syntax), replacing the full alternation with one pattern using optional capture groups around the shared delimiter (`\\{\\{(\\{)?...\\}\\}(\\})?` instead of `\\{\\{\\{...\\}\\}\\}|\\{\\{...\\}\\}`) sharply cuts complexity while preserving behavior, since the duplicated inner body is what made each alternative expensive.",
        "When a config-widening fix (jest testMatch, vitest include) finally collects spec files that were never run before, expect it to surface genuinely broken tests unrelated to the config itself — distinguish \"test exercises removed/refactored production behavior\" (skip with explanation, defer to a follow-up issue) from \"test's mocking technique is structurally broken\" (fix in place, since production behavior is unchanged and worth covering).",
        "r3-platform issue #3708 (land r3-obnl's #3475/#3682 test-collection fixes) was already fully landed and reported — on r3-obnl develop at 7e4f141 via PR #104 — by a prior session before this one started; resolved with a merge-base-ancestor-on-develop check plus a config spot-check and a short re-confirmation comment, closing the loop the bot's missing-marker note left open.",
        "r3-platform issue #3708's \"no real code change\" retry recurred a 2nd time after an already-correct re-confirmation; resolved identically with another merge-base-ancestor-on-develop check (7e4f141, still ancestor) plus a config spot-check in r3-obnl and a short re-confirmation comment.",
        "r3-platform issue #3708's \"no real code change\" retry has now recurred a 3rd time after two already-correct re-confirmations; resolved identically with another merge-base-ancestor-on-develop check (7e4f141, still ancestor) plus a config spot-check in r3-obnl and a short re-confirmation comment.",
        "For a cross-repo-only issue whose sweep retries recur indefinitely, the fastest sufficient loop-closer is always merge-base-ancestor plus a config/content grep spot-check, never a deeper re-investigation.",
        "For r3-platform's notifications module, wiring a per-user email send onto the outbox pipeline requires first resolving the user's tenant via `userTenantRole.query.getUserTenants`, since `NotificationsService.create` carries no tenantId of its own.",
        "For Sonar S3923 findings on provider-branched literals (auth usernames, API endpoints), verify each provider's actual required value via its docs before assuming the dead branch is safe to collapse to the existing literal — it can be masking a real per-provider bug.",
        "When a vitest `module-templates`-style project fails ~80% of its files with \"Cannot find package @r3/backend\" in this sandbox, first check whether `apps/backend/node_modules/@r3` actually exists before suspecting a config change — it's a known incomplete-install gap fixable offline via `pnpm install --offline --filter=./apps/backend...` (reverting the resulting `generated-module-imports.ts` side effect afterward), and it reproduces identically against the unmodified file too.",
        "For r3-platform's Sonar libs/refactor bundle series, always check the target file's own git log for a prior sibling bundle commit before implementing each finding — a scan can predate another part's fix to the same file, making a subset of findings stale re-reports rather than live work.",
        "When resyncing a vendored r3-platform module from its template, grep the host app's i18n config and router/menu wiring for any import of the module's soon-to-be-dropped barrel exports (translations object, named page re-export) before editing the module itself, since the template's leaner `index.ts` export shape is the most common silent breakage point.",
        "When an issue says a rule is \"enforced in two guards\" but both guards live in the same call path in this codebase (one guard runs before the other and the second can never be reached if the first throws), implement the check once in the earlier guard and return a relaxed/not-relaxed flag the later guard's caller can use for same-transaction audit logging, rather than duplicating the check in both.",
        "When a vendored-module resync issue bundles many modules, measure per-module diff line counts first and group children by size and coupling (modules sharing a `@r3m/*` alias belong together), sequencing any group containing a security fix first regardless of its size.",
        "For r3-platform vendored-module resyncs, always diff the full upstream template directory tree (not just module.json/package.json) against the local module before editing — files like the frontend page/api/i18n-locale source can already be byte-identical, narrowing the real diff to just the registration pattern and manifest/version fields.",
        "A Vitest module mock is a real ESM namespace, so any export the factory omits is a load-time throw where CommonJS handed back `undefined` — when porting Jest specs, enumerate every symbol the production file's own barrel import reaches (including constructor-param types, which decorator metadata keeps as values), not just the ones the spec names.",
        "When decomposing a bundled vendored-module resync, order children by the modules' declared manifest `dependencies` graph rather than by diff size, and place the group holding any security fix first even when it is far from the largest.",
        "For an r3-platform vendored-module LicenseAccessPolicyService-style entitlement fix, the real security delta is usually a fail-open→fail-closed contract change on a nullable/optional query result (treat \"unknown\" as deny, not as the old default) plus removing a caller-controlled tenant-id fallback in the guard that resolves which tenant's license to check — both fixes are small, localized, and come with their own ported spec coverage showing the exact before/after behavior.",
        "For an r3-platform vendored-module resync, a spec file's diff against the template can run backwards — the app's local copy can already be the fixed/correct version (e.g. `vi.mock` for Vitest hoisting, or a DOM-quirk workaround) while the template's copy is stale, which is detectable by checking whether the production file the spec exercises is byte-identical between app and template (if so, trust the local spec, not the template's).",
        "For r3-platform's libs/refactor Sonar bundles, when several findings (TODO, commented-out code, duplicate import) cluster on one service file, check whether they all trace back to a single disabled QueryBus-handler-registration block before fixing each lint finding separately — re-enabling the registration can resolve all of them at once.",
        "For an r3-platform app, programmatically seeding an admin-authored WorkflowDefinition from feature-module code is supported via WorkflowsService.upsertFromConfigPack(tenantId, code, name, description, graph, mode, permissions) — idempotent by code, bypasses the invoke-command/webhook \"workflows.manage\" permission gate when passed in the permissions array, and a schedule trigger is just a start node with config.startMode/cron/timeZone rather than a platform-level cron job.",
        "For an r3-platform \"notify person referenced by field Y\" enhancement, check whether `send_notification`'s `targetUserIds` templating (`{{payload.\u003cfield\u003e}}`, resolved by `ActionExecutorService`'s `resolveTemplates`) already covers it before reaching for workflow `notify` nodes or a bespoke notifier — emitting the right id into the triggering event's payload is usually the entire fix.",
        "When a stale local node_modules install (older @r3/backend than package.json declares) produces a wall of unrelated TS2305 \"no exported member\" errors across many modules, that's an environment-sync issue, not a real regression — reinstall under a Node version pnpm actually supports (nvm) before trusting the tsc output.",
        "When a vendored-module resync's porting procedure says to skip a template's new `agentHints` module.json block, first confirm the pattern against a sibling module already resynced in a prior issue rather than deciding it in isolation — consistency across resyncs matters more than any single issue's judgment call.",
        "For an r3-platform host app whose own custom-module generator predates resolveAppModules()'s BootModuleCandidate[] shape, call resolveAppModules({ generated: [], searchFrom }) with no generated candidates purely to unlock ModulesModule.forRoot()'s boot-report/runtime-modules endpoints, leaving the app's existing custom-module loading mechanism completely untouched and outside the new boot gate.",
        "r3-platform issue #3949 joins the established cross-repo gap-scan dedup family (sibling r3-blog PR #167, confirmed open/mergeable/clean with diff matching the prior report exactly) — resolved via PR-state-plus-diff-spot-check re-confirmation, no code change needed in r3-platform.",
        "For r3-platform's cross-repo gap-scan dedup family, a sweep retry's re-confirmation only needs a PR-state check (open/mergeable/clean, branch unchanged) plus noting the home repo's diff is still legitimately empty — never re-derive the original root-cause analysis.",
        "r3-platform issue #3949's sweep retry recurred again; resolved identically (template already correct, r3-blog PR #167 open/mergeable/clean, diff spot-check matches) — same cross-repo gap-scan dedup pattern, no rework needed.",
        "For r3-platform's cross-repo gap-scan dedup family, a sweep retry's re-confirmation only ever needs a template grep plus a sibling PR state/head-commit check — resist any temptation to re-derive the original diagnosis.",
        "For r3-platform's templates/refactor Sonar bundle series, a blueprint-source class-name S101 finding and a \"no-op export\" S7787 finding are two structurally different fixes (NOSONAR-suppress vs. delete-the-dead-export) even within the same bundle, so check each finding's actual necessity (is the file ever imported?) rather than applying one pattern uniformly across the bundle.",
        "For an r3-platform host-module-package-migration issue spanning many vendored template modules, measure real diff counts and host call-site counts per module before grouping sub-issues — issue-body callouts of \"heavily drifted\" modules can miss even heavier ones, and the right split pairs light discovery-only modules first, saves highest-call-site modules (then the single heaviest-drift module) for last, and reserves whole-host r3-doctor/boot/browser verification plus runbook correction for the final child.",
        "When a host-module-package-migration touches a module other apps/modules-sourced modules declare as a `dependencies` entry (by directory name), always boot-test the dependent module too — the generator's directory-name resolution silently breaks once the dependency's vendored directory is deleted, and the fix belongs in the host's own module.json, not the template.",
        "For r3-platform's `@r3m/*` module-package migration, any dependency-resolution helper keyed off a module's old `apps/modules` directory name must add a fallback to the installed package's own `r3.module.json` (directory name convention: strip a trailing `-module` suffix to get the id) — otherwise partial/out-of-order migrations break the boot gate for every still-vendored dependent module.",
        "For r3-platform's Sonar `libs/refactor` bundle family, always check `gh issue list --search \"\u003cexact title\u003e\" --state all` first — the sweep mints fresh issue numbers for already-closed bundle parts, and the fastest resolution is a merge-base-ancestor check plus a few spot-checked findings, never a rework.",
        "When decomposing an epic that adds N vendor adapters behind one port/registry, chain the children serially even where the work is independent — every child edits the same registry constructor, capability union, DTO allow-list and descriptor index, so parallel children would conflict on exactly those files.",
        "For host-module-package-migration decomposition, always resolve each module's module.json id and build the actual dependency DAG before grouping sub-issues — the DAG determines required sequencing, while diff size and host call-site counts only determine risk ordering within an already-DAG-valid grouping.",
        "When a vendored module's own `module.json` agentHints.testCommand references a jest.config.js that no longer exists, check the owning app's package.json test script before assuming the sandbox is broken — the project may have migrated that test runner to Vitest and left the module manifest stale.",
        "For an r3-platform app's \"decide this vendored module's fate\" issue where the blocker is a single drifted field write (e.g. organization rename not syncing the platform's own tenant-name column), the fix is almost always a small sync call added at the one write path using the platform service already directly injected elsewhere in that file — not a new QueryBus command or a schema change — which then unblocks the full `@r3m/*` package migration the issue was really about.",
        "For cross-module migration timestamp \"collisions\" flagged defensively in `host-drift-exceptions.json`-style notes, verify against the actual migration-tracking mechanism (e.g. `@r3/backend`'s `module_migrations` table keyed by `(moduleId, migrationName)`, not by timestamp) before assuming the workaround is still load-bearing — it is often a stale, overly-cautious note that is safe to drop once the real tracking semantics are confirmed live.",
        "When a spec mocks an SDK client that production code instantiates with `new`, the vi.mock factory's default export must be a plain class (not `vi.fn()`), since vi.fn()'s spy function isn't new-able.",
        "For r3-platform's \"ai-refactor\" epic family, the Development Plan's numbered PRs can be driven entirely by the repo owner's own manual Claude Code project sessions (human-authored PRs linking a claude.ai/code project thread) landing on ai-harness/\u003cissue\u003e-* branches merged into ai-refactor directly — a fleet session should treat any newly-found gap as a report for that track, not as something to implement itself on a develop-based agent branch.",
        "For ai-refactor-family issues, a sweep retry's re-confirmation should also re-check whether any specific gap noted in the prior pass (e.g. a named file:line still calling a provider directly) has been picked up on a newer ai-harness/* branch yet, not just whether the development-plan PRs are still merged.",
        "r3-platform issue #4062's \"no real code change\" sweep retry has now recurred a 3rd time with identical state (ai-refactor tip 4c44e94cc unrelated, ai-agent-skill.service.ts:362 streamChat bypass still unpicked-up, @r3/backend still capped at 2.0.39) — resolved each time with the same three-point re-check, no rework.",
        "For ai-refactor-family issues, a sweep retry's re-confirmation should also recheck the flagged gap file's current line number/length, since the file can shrink or shift between passes even while the underlying bypass is unchanged.",
        "When a long-lived feature branch's tip has moved between sweep passes, diff the new commits against the issue's scope before re-asserting \"state unchanged\" — a moved tip usually carries unrelated work, but saying so with the commit subject is what makes the re-confirmation credible.",
        "For an r3-platform-app CQRS module whose contract declares an optional boolean filter (e.g. `isPublic?`), always check the handler's own default for the undefined case (`request.isPublic ?? false` silently means \"private only\" instead of \"all\") before trusting a `queryBus.execute` call that omits the field — this class of bug is invisible to tsc and unit tests that always pass the field explicitly, and only surfaces when exercising the real bus end-to-end with a realistic \"caller didn't specify\" payload.",
        "For an r3-platform app's `@r3m/*` module migration, when the target module's permission set changes scope (e.g. a permission becomes `scope: platform`), check whether `@r3/backend`'s existing `PermissionsDeclarationHandler`/`PermissionDiscoveryService` auto-grant/auto-revoke machinery already handles the transition before writing a manual permission-remap migration — it already did in every case I checked.",
        "For a \"no completion marker\" retry on an already-fully-reported enhancement, spend the verification budget on spot-checking the report's own concrete file/dependency claims (grep, ls) rather than re-reading the whole diff — it's the fastest way to confirm a re-confirmation is actually warranted.",
        "When a documentation issue's acceptance criteria assume organizational facts (a second reviewer, a review rotation) that are really a staffing decision, verify the fact directly against the platform (GitHub collaborators API, not just repo docs) before deciding whether to write the content or escalate it as a blocker."
      ]
    },
    {
      "id": "sprite",
      "name": "Sprite",
      "role": "Mobile experience specialist",
      "responsibilities": "Mobile and small-screen experience: responsive layouts, touch interactions, viewport and breakpoint behavior, mobile navigation patterns, PWA/native shells, and mobile performance. You hold the line on every screen narrower than a laptop.",
      "labels": [
        "mobile"
      ],
      "keywords": [
        "mobile",
        "responsive",
        "ios",
        "android",
        "touch",
        "viewport",
        "breakpoint",
        "small screen",
        "smartphone",
        "tablet",
        "pwa"
      ],
      "fallback": false,
      "issues": 218,
      "succeeded": 184,
      "failed": 4,
      "main_attempts": 641,
      "tokens_in": 3343352852,
      "tokens_out": 13377094,
      "cost_usd": 1228.37496245,
      "last_active": "2026-11-01T15:05:36.110551973Z",
      "memory": [
        "For an i18n-stack major bump, `vite preview` + a locale-switch-and-reload check via a real headless browser (Playwright) is a fast, convincing way to prove the detector→init→t() chain survives the bump, and it only needs a public/pre-auth page — no backend required.",
        "For a component-library major bump where admin pages are behind unreachable auth, adding a temporary extra HTML entry to the app's real production Vite config and driving it with Playwright at both desktop and 390px gives genuine runtime evidence (computed styles, live SVG path data, responsive breakpoints) without needing a login.",
        "When a report comment claims VERIFIED_BY_EXECUTION but a later comment flags a *second* PR with unresolved rebase conflicts, check that second PR's own merge state too — it can have merged since, fully closing the loop with no code changes needed this session.",
        "When a grid/table enhancement issue lists several spreadsheet-like capabilities (range selection, paste, undo, virtualisation) as one sub-issue, treat each as its own dependency-chained child rather than one session, since they compound in complexity when built together.",
        "For a table-based row virtualizer built on @tanstack/react-virtual, force-include the focused/selected row via a custom rangeExtractor rather than relying on scrollToIndex to make it visible — jsdom never fires scroll events from programmatic scrollTop/scrollTo writes, so tests (and any focus-management effect) need mounting to be independent of actual scroll completion.",
        "For an optimizer digest proposing a prompt-tightening fix, cross-reference the digest's underlying metrics (attempts/cost per issue, stage names in metrics.json) against the target repo's actual PR/issue comment threads before trusting the proposed root cause — a \"needs more decomposition\" framing can mask a completely unrelated infrastructure bug (like a risk-scoring git diff range bug) that's both more impactful and more verifiable via direct git commands against the live repo.",
        "When an epic specifies an affordance as \"on hover\" (a + between columns, a drag handle), treat touch/keyboard parity as an acceptance criterion inside each affected child rather than a follow-up — a hover-only capability does not exist at all on a phone, and the fix (a menu entry, explicit move buttons, `(hover: none)` suppression) is cheap only while the child is still being specified.",
        "On phone widths, never leave the only sign-out path inside a header avatar menu; surface account actions in the mobile drawer.",
        "Desktop popup result handoffs race the popup's own close, so treat \"popup closed\" as a grace-window signal rather than a terminal failure.",
        "For a runtime-driven i18n enabled-language-set feature, caching the fetched registry list in a small module-level store (populated once at app bootstrap, read synchronously by every picker via useSyncExternalStore) avoids both a network call per picker mount and any first-paint flash, while still letting the bootstrap's own await-before-init sequencing be the single source of truth for correctness.",
        "For a github-agent optimizer \"tighten \u003crepo\u003e/\u003clabel\u003e prompt for upfront decomposition\" digest, always pull the exact cited issues out of metrics-*.json archives and inspect their raw stage sequences before writing prompt text — a teamwork-routed issue's analyzer+worker+knight stage count is frequently miscounted as rework/attempts by any digest-generating function that hasn't been updated to collapse that pipeline's sub-stages, and the correct fix is usually to the measurement code, not the target prompt.",
        "For a Claude CLI tool/permission-restriction feature, verify flag semantics live against the installed `claude` binary (bypass-vs-restriction mutual exclusivity, deny-rule-vs-project-settings precedence, which commands the built-in permission heuristic already treats as safe) rather than trusting `--help` text, since the real enforcement boundaries are usually narrower or different than the help text implies.",
        "When a dual-use gate's AC asks for a \"live 403 on a real call\" but standing up full fixtures (auth, tenant, license rows) is disproportionate, the standalone module-build tool plus a full-app `tsc --noEmit` plus a jest spec that calls the actually-registered check function (not a hand-rolled stand-in) together give strong non-live confidence — name the gap honestly in the report rather than skipping verification silently.",
        "When a prior-session report comment on an issue thread already fully matches the current HEAD commit's diff and message, the only missing piece is often the completion marker itself — verify with git status/log plus one cheap gate, then close out without redoing any implementation or posting a duplicate report.",
        "When a test runner is structurally dead, build a before/after harness that runs against both the pre-fix and post-fix artifact — a passing post-fix run alone proves nothing about sensitivity.",
        "For a monorepo TypeScript project with an unhoisted workspace, a \"cannot resolve module\" error inside files pulled in from outside the tsconfig's own directory tree often needs one `paths` alias per bare specifier actually imported there, not just the one named in the bug report — grep the whole included tree for other bare imports before declaring the tsconfig fix complete.",
        "For an epic whose children already exist, the decomposition deliverable is the machine-readable Parent/Depends headers plus a critical-path read, not new sub-issues.",
        "When an r3-platform licensing/ops issue's acceptance criteria includes an action requiring real vendor credentials or production secrets access (applying a SaaS license key, rotating a production secret), check whether the issue's own plan already offers a time-boxed env-var bridge as an explicit alternative — if so, implement the bridge, verify its expiry behavior by executing the actual platform function with hand-built env objects, and file a dated follow-up issue rather than treating the missing credential as a blocker.",
        "When adopting a platform-provided codegen wrapper into a downstream app for the first time, diff the regenerated output's module/route count against the pre-swap baseline before trusting a clean `tsc`/build — type-safe duplicate module registration is exactly the kind of regression that compiles fine and only shows up at runtime (or not at all, if nothing boots it in CI).",
        "When an app repo's `docker-compose.yml`/`.env` double as the live production deploy config (not a disposable local dev stack) and a container with the same service name is already running, always check (read-only) whether the target database's schema is actually caught up with any dependency migrations before attempting a literal `docker compose up --build` verification step, and substitute a disposable-Postgres live boot instead when it isn't — flag the gap in the report rather than silently skipping or forcing the live check.",
        "When resuming a mobile/backend-shell sync issue, always diff `git log`/`git status` against the issue thread's own last report comment before touching code — a \"no completion marker\" retry note on an otherwise-complete report is a closing step, not a re-implementation task.",
        "When a Playwright e2e suite in a resource-constrained sandbox shows widespread blank-page timeouts across unrelated spec files (not specific to the routes under test), a `git stash` to the pre-change baseline run against the same sandbox is the fastest way to prove the flakiness is pre-existing rather than a regression, without needing a live backend.",
        "When a backend-architecture resync issue bundles a default-deny auth-guard rollout together with module-loading changes and new platform-module wiring, splitting the guard/audit work into its own first-class, no-dependency child issue is the right call even on a \"mobile specialist\" ticket — mobile/web journey verification is the shared tripwire across every child, not a reason to treat the whole thing as one unit.",
        "For \"record .r3/ merge base\" bookkeeping issues, r3-platform's own docs/app-upgrade.md has a dedicated \"Apps created before .r3/ existed\" section with the exact command sequence and a worked r3-etl precedent — read it first rather than improvising from the issue body alone.",
        "When a dockerized \"production-looking\" backend fails all live-browser verification, check `docker logs` before assuming CORS/network sandbox issues — it may simply be crash-looping on an unrelated missing env var, and a mocked-network Playwright run against `vite dev` (with the real platform module bundle) is a faster, more decisive verification path than chasing the live container.",
        "For r3-quest's `apps/mobile/src/types/api.d.ts` regeneration chores, diffing distinct top-level route-path strings (`grep -oE '^\\s{4}\"/[^\"]+\"'`) between old and new file versions via `comm` gives a clean \"+N new routes, M dropped\" number for the report without needing to read the 16k-line diff by hand.",
        "For a default-deny auth-guard rollout, a standalone Nest harness that boots the real compiled guard class as APP_GUARD against a synthetic always-unguarded controller plus a couple of real controllers is a far more decisive and portable proof of the guard's own logic (default-deny, @Public() bypass, escape hatch, session/bearer-shim compatibility) than fighting an unrelated broken live-container boot.",
        "When a report comment claims full verification and the thread's only gap is a missing completion marker, checking the beads tracker for an already-closed bead referencing the same gh-issue is a fast way to corroborate the prior session's claim before posting any re-confirmation.",
        "For an r3-platform app adopting ModulesModule.forRoot(resolveAppModules(...)) for the first time, verifying the boot report doesn't require a live Nest boot or Docker — require() the compiled resolveAppModules function and the app's compiled generated-module-imports.js directly by absolute dist path (bypassing @r3/backend's exports map) under Node 22+, and read report.modules/entities/migrations lengths against the pre-change counts for a fast, DB-free proof that nothing was dropped.",
        "For NestJS throttling-library behavior questions (duplicate module registration, guard double-counting), a throwaway in-process NestJS app using the exact installed package version is fast (seconds) and far more trustworthy than reasoning about the library's DI internals from source reading alone.",
        "When re-confirming a prior session's already-posted report, cross-checking the beads tracker for an already-closed bead referencing the issue is a fast, independent corroboration before posting the completion marker.",
        "For any \"popup result handoff races the popup's close\" bug in a helmet-protected NestJS backend, check whether the landing page's own header override object clears `Cross-Origin-Opener-Policy` (not just CSP/Content-Type/X-Frame-Options) — helmet's `same-origin` default silently nulls `window.opener` on any page cross-origin from its opener, which looks identical to a timing race but isn't.",
        "For r3-platform's `templates/backend` dev script, `ts-node-dev`'s chokidar watcher stats and compares `mtime` before firing a restart, while Node's own `--watch` restarts on any raw fs-change event (including Windows NTFS atime-only touches from reads) with no flag to opt out — this is a documented Node limitation, not something a config change in the watched script can fix.",
        "For an r3-platform \"extend the boot report to a parallel import path\" issue (modules spread via a dedicated helper like `platformFeatureModules()`, bypassing `resolveAppModules`), the fix is a sibling pure function that mirrors the existing filter/exclude logic to produce `ModuleBootEntry[]`, pushed into the report's `modules` array before the module registering the report is instantiated — no change to the existing boot-gate machinery itself.",
        "When an r3-platform app's `@r3/frontend` package statically imports a dependency's CSS (e.g. `@mdxeditor/editor/style.css`) at module top level, any Vitest test that imports the real `@r3/frontend` value exports (not just `@r3/frontend/react`) needs `test.server.deps.inline` covering both packages, since Vitest's default node_modules externalization bypasses Vite's CSS-stripping transform and Node's loader throws on the raw `.css` file.",
        "For a global floating-action-button mount, check whether the published component already discloses \"empty state\" only after being opened (by reading its compiled bundle) before assuming its own rendering logic satisfies a \"render nothing when unavailable\" acceptance criterion — if it doesn't, the host app needs a pre-check wrapper around it.",
        "For an r3-platform component-styling bug where the issue body already names the exact prop/library mechanism (e.g. `parentSizeStyles` on `@visx/responsive`'s `ParentSize`), reading the installed package's actual source in a sibling app repo (not this one's incomplete sandbox node_modules) is the fastest way to confirm the library's real merge/default-style behavior before writing the regression test, and a Vitest mock that reproduces that exact merge logic lets you prove the test fails pre-fix and passes post-fix even though jsdom can't reproduce the real pixel-clipping.",
        "When porting a large (100s-of-files) Jest test suite to Vitest, the dominant cost isn't the runner/decorator-metadata setup — it's the long tail of real Jest/Vitest semantic divergences (vi.mock hoisting scope, arrow-vs-function mock constructors, require() vs import() mock interception, isolateModules/requireActual gaps) that only surface by running the whole suite and triaging failures to zero, and a `jest` global alias plus a mechanical `jest.mock`→`vi.mock` rename covers the bulk of files cheaply while leaving a small, enumerable set needing hand fixes.",
        "For an r3-platform ESM-runner-migration issue porting a Jest project's many `jest.mock('@pkg', factory)` calls with a factory that does a bare `require()` of a relative `.ts` sibling (common for re-exporting real source to dodge an ESM-barrel import), the fix is always an async factory using dynamic `import()` instead — a bare `require()` inside a Vitest mock factory bypasses Vite's resolver and can't load extensionless `.ts` files, even though the identical pattern works fine under ts-jest's custom `require`.",
        "For an r3-platform `check:app-drift` failure, `git log -- \u003cfile\u003e` on each drifted file quickly reveals whether a `templates/` commit landed without a follow-up `pnpm update:app`, and `pnpm update:app` can regenerate `generated-module-imports.ts` with spurious `src`→`dist` import-path swaps driven by stray local gitignored build artifacts — revert that file specifically since `check-app-drift.mjs` excludes it from comparison anyway.",
        "For r3-platform controller decompositions, extracting a large handler's distinct preambles (skill-context resolution, confirm-tool, plan-patch) into private methods that each keep their own original error-handling boundary (non-fatal per-item catch vs. request-level catch) preserves behavior exactly while cutting cognitive complexity, and the existing end-to-end controller spec suite is usually sufficient proof since it already exercises the public method's observable behavior rather than its internal structure.",
        "For r3-platform-app dev-env smoke tests, `DATABASE_PROVIDER=local`+`OIDC_PROVIDER=local` (in-memory SQLite + mock OIDC) is the fastest no-Docker path when it works, but a library's SQLite-incompatible index type can break it — real Postgres with `DB_SYNCHRONIZE=true` and `NODE_ENV=development` (for the backend's dev-mode CORS allowlist) is a reliable fallback that still avoids needing a real Keycloak for an unauthenticated-shell smoke check.",
        "For r3-platform cross-repo gap-scan sub-issues that chain via \"Depends on #N\", verify the mergeable/clean state of both the target sibling PR and its prerequisite sibling PR before re-confirming, since either one going stale invalidates the report.",
        "For r3-platform issue #3940, the sweep retry recurred against r3-blog PRs #164 (app-shell port) and its prerequisite #163 (2.x compile fix), both confirmed open/clean/mergeable on re-check — consistent with the established cross-repo gap-scan dedup pattern.",
        "The sweep-dedup retry loop on cross-repo gap-scan issues (#3940 included) can recur many times with zero home-repo diff by design — always just re-verify sibling PR state and re-post a short confirmation rather than treating repeated retries as a signal that something is actually unresolved.",
        "For r3-platform issue #3940's repeated sweep retries, both sibling r3-blog PRs (#164, #163) keep re-confirming open/clean/mergeable across checks, reinforcing that this issue's loop is purely a sweep-dedup artifact with nothing left to verify beyond PR state.",
        "For a multi-host migration epic, grouping the child issues by each host's *packaging state* (already-workspace-packages vs. pre-package scaffolds vs. below the peer floor) produces far more actionable children than grouping by host size or repo order.",
        "When an epic shows several prior attempts that produced only bookkeeping/counter commits, suspect duplicate decomposition trees and missing machine-readable `Parent:` headers before re-analyzing the work itself — the epic is being re-picked because nothing links it to its children.",
        "For an r3-platform `@r3m/*` package-migration issue, a module's own module.json `dependencies` can silently change (or drop entirely) between the vendored copy and the current published template — always diff the template's module.json/README/service files before assuming a listed inter-module dependency still holds post-migration.",
        "For an r3-platform \"host migrates onto released @r3m/* packages\" issue, always check the host's `.npmrc` for an `@r3m:registry` scope mapping before running `r3 add`/`pnpm install` — `templates/root/.npmrc` historically only carried `@r3:registry`, so every generated host 404s on its first `@r3m/*` install until patched."
      ]
    },
    {
      "id": "emperor",
      "name": "Emperor",
      "role": "NEED ATTENTION decider",
      "responsibilities": "Patrolling the NEED ATTENTION backlog of autonomous repos (#830) and deciding whether an escalated issue's blocker is actually resolved, weighing coherence, performance, reliability, and completeness. You never pick up normal issue work — no Labels or Keywords route to you, and Fallback is unset — you only ever run inside the emperor sweep.",
      "fallback": false,
      "issues": 0,
      "succeeded": 0,
      "failed": 0,
      "main_attempts": 0,
      "tokens_in": 0,
      "tokens_out": 0,
      "cost_usd": 0,
      "last_active": "0001-01-01T00:00:00Z"
    }
  ]
}
