Build portal bug submissions, known issues and Forgejo AI triage workflow
Closure: user confirmed production deployment and accepted closure. Historical validation notes and unchecked checklist items below are retained; closure does not assert independently rerun checks. Goal: replace direct player use of the Git issue system with authenticated, submission-only reporting in PRK.PlayerPortal and a read-only catalogue of triaged known issues. Forgejo remains the canonical issue tracker; include a daily, independently deployable code-aware LLM triage worker. Start clean with fresh reporting repositories; migration of legacy issues is deferred to separate future work and is not a launch dependency. Implementation authorized by user. Work starts with the portal domain/authentication/submission and attachment lifecycle, then Forgejo integration and the new worker. Upload defaults are five files, 25 MiB each, 100 MiB per report; daily triage defaults to 03:00 UTC. User explicitly excludes deployment/cutover rehearsals, backup/restore rehearsals and database rollback strategies from this work. Retain normal functional, security and regression validation. Proposed flow: players search known issues, submit structured reproduction/expected/actual/environment details, receive a receipt, and later see the triaged outcome. Players cannot edit, comment, message, or change issue state. No untriaged content is visible to players, including their own reports; a submission receipt may confirm acceptance without exposing the queue. Published catalogue supports search, pagination, status/category filters and My reports using private account-to-report mappings; duplicate reports resolve to a canonical known issue. Publication is an explicit allowlisted state, not absence of a needs-triage label. Confirmed visibility: submission and catalogue both require portal sign-in; there is no anonymous catalogue. Use fresh private repositories throughout this reporting system. Created private repositories: prk/player-bug-intake for staff-only raw intake shared by both submission paths, prk/player-known-issues for the general curated tracker, prk/spiritech-known-issues for the beta-restricted curated tracker, and prk/player-reporting-worker for new worker code/workflows. All four were verified private and empty with only Owners, Developers and Management team access; no initial commits were created. Legacy trackers and beta automation were left unchanged. Do not continue using, modify, change visibility of, import from or launch against prk/issues, prk/issues-private or the existing Spiritech beta issue tracker. Legacy migration is deferred. Existing repositories may inform reusable code/patterns, but are not live destinations for the new workflow. Only the portal exposes a player-facing list, after authentication. Players receive no direct access to the underlying Forgejo issues. Keep raw reports and reporter identity private; publish only sanitized titles/descriptions/status/category and portal canonical links. Site DB holds durable submission/delivery records, private issuer+subject ownership, Forgejo identity mappings and a rebuildable public projection; it is not a second editable issue tracker. Commit submission plus delivery intent atomically; retry API delivery with stable correlation IDs and reconciliation after ambiguous timeouts to avoid lost or duplicate issues. Forgejo API is server-side only, using dedicated scoped credentials. Portal never renders raw issue comments, reporter contact data or arbitrary internal metadata. Worker implementation is in the fresh local repository /home/mathias/Projects/player-reporting-worker (origin prk/player-reporting-worker), using pinned Node/TypeScript/Pi packages. The portal owns durable orchestration and the restricted Forgejo executor so write credentials and authoritative audience routing never enter model analysis. The separate controller/analyzer communicate with the portal through a dedicated bearer-only versioned API. Reuse inspected runner patterns where appropriate, but do not extend or change the live prk/triage-runner or its existing beta workflow. General and Spiritech reports use the same worker implementation and pipeline, with server-controlled product/audience routing rather than separate implementations. Daily/manual deployment templates are implemented for 03:00 UTC: Forgejo Actions invokes a restricted SSH host wrapper, or an optional systemd timer invokes the same wrapper. Choose one scheduler. The wrapper accepts only normal/dry-run commands and takes a host flock; SQL report/decision leases also protect concurrent work. Production activation is not performed. Deploy a pinned worker image, not a daily redeploy of Forgejo. Existing beta workflow runs every eight hours with Claude Code; its prompt also contains implementation/PR creation behavior that MUST NOT be inherited by the player-report mode. Read issue corpus plus allowlisted code repositories at recorded revisions; retrieve duplicate candidates before model analysis. Model returns schema-validated categorization/routing/priority/duplicate/public-summary proposals with evidence and confidence; separate deterministic executor enforces allowed repositories, labels, transitions and publication. Use ChatGPT through the Pi harness for the code-aware analysis worker. Begin with dry-run evaluation before enabling bounded non-destructive categorization/routing/publication. The LLM must not perform destructive actions: do not delete reports, issues or attachments, or erase original evidence. Mark uncertain, conflicting or sensitive outcomes as needs-staff-review and keep them unpublished. Staff review and overrides happen entirely inside Forgejo using labels and internal audit comments; do not build a portal moderation interface. Duplicate automation should link/mark candidates without deleting evidence; automatic closure is not included without an explicit later decision. Human decisions take precedence and reruns do not overwrite staff changes. Treat reports and code as untrusted model inputs; sandbox analysis with read-only code, no production secrets, no unrestricted command execution or arbitrary network access. Keep Forgejo write credentials outside model analysis. Use a dedicated Pi configuration with only approved read-only code/evidence tools, not the operator's unrestricted tools or credentials. Local headless SDK request is verified with openai-codex/gpt-6.1-sol using ChatGPT OAuth, zero tools, custom ResourceLoader, no repository resources and an in-memory session. Synthetic JSON output was parsed and validated. Pin both Pi version and an account-supported model; catalog presence is insufficient (gpt-5.5 and gpt-5.3-codex-spark probes were rejected). This proves local execution, not the Git-host service account, refresh lifecycle, provider terms or data policy; provision dedicated service authentication and test restart/refresh there before enabling scheduled runs. Define data minimization and attachment-to-model policy before sending private evidence. Reuse evidence: portal is .NET 8 Razor Pages with Keycloak OIDC, role policies, server context, EF Core SiteDataContext, embedded additive PortalSchemaMigrator, HttpClient registration and existing Tailwind/Razor layout. Forms have immutable submissions, validation/rendering, issuer+subject identity and external read API conventions; reuse or narrowly extract these helpers without adopting FormService's one-submission-per-user-per-form restriction. Bug reports need their own lifecycle and repeated submissions. Forms read token must not grant issue-worker write access. Extend AOEmu.UnitTests/PlayerPortal HTTP/auth/encoding and opt-in disposable MSSQL test patterns. Remote discovery found prk/triage-runner, prk/forgejo-mcp and prk/forgejo-mods. Reviewed all three runner files (Dockerfile, triage-run.sh and workflow), the beta daily-triage prompt, MCP issue tools/client/config and board README. Reuse runner image/schedule/checkout conventions and API/attachment parsing experience; do not load the broad writable MCP server directly into model analysis or copy its unbounded attachment downloads. Existing beta triage labels/request markers are useful reference only, not a shared lifecycle. Forgejo board and normal issue UI already provide staff workflow; no portal admin triage pages are needed. Existing portal-scoped Kamal deployment can carry portal changes; worker deployment stays in the new worker repository. Inspection of Auth/PortalClaimsTransformation.cs confirms current normalization covers resource_access roles but scans every client. Add a dedicated portal-client-scoped spiritech_beta permission, not a broad all-client role match. Do not reuse bug_hunter/developer or other existing game roles: bug_hunter also grants game privileges through PortalRoles.GmLevelFor. Do not introduce a SPA, parallel authentication or generic workflow platform. Acceptance: authenticated players can repeatedly submit distinct reports with CSRF, validation, size and rate limits; cannot access pending reports by listing, guessed ID, search, API or cache; can browse only approved sanitized known issues and their own published mappings. Reports survive Forgejo outages and process restarts without duplicate delivery. Daily/manual worker safely classifies, routes and deduplicates using code evidence; invalid model output cannot mutate Forgejo; uncertain outcomes await staff inside Forgejo and destructive model actions are prohibited; reruns and concurrent runs are idempotent and respect human edits. Staff can inspect/retry failures, approve/reject proposals and revoke publication. Forgejo status/visibility changes reconcile into the catalogue without leaking raw content. New repositories begin empty. Legacy issue migration/backfill is explicitly outside initial implementation and launch acceptance. Relevant portal/worker tests, sandbox Forgejo contract tests and authenticated browser workflow pass before rollout; confirm installed API permissions, issue move/link behavior and scheduling capabilities during implementation. Required first-release attachments: screenshots, logs and arbitrary file types. Chosen storage design: private durable portal staging volume for streaming upload/quarantine/retry, then native private Forgejo issue attachments for long-term evidence. Upload allowed extensions normally; server-wrap unsupported extensions in a safe generated .zip envelope preserving original bytes and recording original filename, size and SHA-256. A real ZIP containing an unsupported-extension file passed Forgejo upload/download checksum tests. Do not change the instance-wide file allowlist or introduce object storage for this release. Store receipt/file manifests and Forgejo asset IDs/UUIDs in SiteDataContext. Evidence stays associated with intake and canonical issues through private cross-links; avoid copying every duplicate's attachments into the canonical issue. Remove a delivered staging copy only after asset verification; deterministic retention/orphan cleanup is separate from, and unavailable to, the model. Propose configurable initial limits of five files, 25 MiB per file and 100 MiB per report; document limits in the UI and align multipart/proxy limits. Files and blobs never go under wwwroot, container-only temporary storage or the shared GameData mount. Preserve files and their report association across delivery retries, crashes and issue routing. Apply configurable file-count/per-file/total/account quotas, streaming upload limits, safe generated storage names, checksums and quarantine/malware scanning. File support does not imply execution, inline rendering or automatic model ingestion. Serve downloads only through authenticated authorized handlers with safe content disposition; untriaged files are not player-accessible, and attachments are not published automatically with a known issue. Model extraction must be sandboxed, bounded and resistant to embedded prompt injection; do not execute uploaded binaries or unrestricted archive contents. Public-facing approved evidence, if later needed, must be separately sanitized and explicitly published. Tests must cover oversized/malformed uploads, path traversal, active content, malware/quarantine failure, unauthenticated/guessed attachment IDs, partial uploads, crash/retry and retention/orphan cleanup. Spiritech Beta path and authorization: - Use a dedicated Keycloak client role named spiritech_beta on the portal client, rather than requiring a group. Add General as the submission path for signed-in users and Spiritech only for users with this permission. Product is independent of game-server selection; both paths share forms, attachments, delivery, triage and publication services. - Read the exact spiritech_beta role only from resource_access[configured portal client ID].roles in trusted OIDC claims. Ensure the portal client's token/claims mapper emits that role. The same role name under another client must not authorize beta access. Do not infer access from unrelated staff/game roles or accept role/product/audience authority from form fields. Missing/malformed claims fail closed. Do not broaden game GM permissions or existing forms management policies. - Implement one shared beta-access policy/helper for navigation, GET/POST authorization, catalogue and file access. Bind product to server-owned audience/destination configuration. No implicit administrator/developer bypass is included; staff triage stays in Forgejo. A group may be used administratively to assign the role later, but runtime authorization requires only the portal client role. - Spiritech published known issues and published My reports are beta-only. General users must not learn beta titles, counts, categories, attachment names, duplicate targets or IDs through routes, APIs or caches. Role removal removes beta access within a defined bounded OIDC/session revalidation interval; re-login picks up new assignments. Do not extend stale beta authorization indefinitely through sliding cookies. - Store immutable product/audience through delivery, proposals and publication. Only the configured curated repo for that product is permitted. Shared staff-only intake remains private. Neither LLM output nor a duplicate match can downgrade a beta report to general visibility; cross-audience duplicates stay internal unless staff explicitly approve a separate general-safe summary. - Acceptance: real beta-role login sees and can use Spiritech; ordinary users, unrelated roles, wrong-client spiritech_beta and crafted POSTs cannot access beta data. Test malformed/missing claims, role revocation/expiry, guessed identifiers and cross-audience report/file/duplicate/cache isolation. User confirms the spiritech_beta role and a group assigning that role have now been created in Keycloak. This configuration decision is locked in: the group manages assignment, while portal authorization checks the role. During implementation verify the actual client ID, emitted claim shape and mapper with a real login; creation is user-confirmed, not independently validated. No group-membership check is required at runtime. Implementation-ready decisions and contracts: 1. Portal owns immutable submissions, account ownership, attachment manifests/scan/delivery state, durable outbox, publication snapshots and private report-to-canonical mappings. Reuse additive embedded migrations and scoped services. Extract stable issuer+subject identity from FormService for reuse; keep bug lifecycle separate from one-response forms. Razor POST handles submission/antiforgery; player listing/detail/search are authenticated and never query raw pending issue bodies. No editing, chat, comments, voting or portal moderation interface. 2. Delivery worker uses a durable lease per report and a stable opaque correlation marker in the intake issue. Reconcile all issues in the bounded delivery-time window with pagination and exact marker matching after ambiguous POST results; do not depend on indexed q search or retry POST blindly. Because Forgejo exposes no verified idempotency-key contract, an unresolved ambiguous create must stay in reconciliation/staff review rather than risking another POST; do not claim exactly-once delivery from a marker alone. Retry attachments separately with stable generated names, expected byte sizes, IDs/checksums and exact asset-list reconciliation. Mark the report ready for triage only when attachments have terminal scan/delivery outcomes. Scanner unavailable means retry/quarantine, not bypass. A clean upload receipt does not expose queue contents. 3. No documented issue-move API exists in the installed Swagger. Use non-destructive create-and-link: retain original intake issue/evidence, create or link a curated canonical issue, then add processed/duplicate labels and internal audit comments. No model-driven issue closure, deletion, comment deletion, original-body rewriting, code implementation or PR creation. Reuse existing area/*, priority/1..4, type/* and state/* taxonomy from prk/issues; add a separate triage namespace and publication labels without equating triaged with verified/fixed. Missing information/uncertain cases become triage:needs-staff-review; staff hold/override takes precedence. 4. Separate orchestrator/Forgejo credentials from Pi. Prefetch allowlisted code at recorded commits; sandbox analysis without repository-discovered extensions/instructions, git credentials, Forgejo write tokens, shell, Docker socket or arbitrary network tools. Expose bounded repository-scoped read/search and clean evidence tools; constrain realpaths and symlinks. Images/log excerpts may reach ChatGPT only through bounded type-specific extraction with data minimization; other files remain stored evidence, never executable inputs. Use a versioned validated proposal contract, evidence references, output limits, per-report wall-clock/token/tool-call bounds and explicit failure states. Orchestrator and executor retain durable idempotent decisions; do not expect the model prompt to provide locking or recovery. 5. Staff review uses Forgejo labels and internal comments only. For a clear result the executor can create a sanitized canonical title/summary and explicit publication record; uncertain/sensitive cases stay unpublished. Keep the original report and internal code analysis outside the public summary. Publication binds an exact sanitized proposal hash, a distinct durable PublicationId for each approval revision and successful executor completion. Terminal staff-review handling is not successful publication. Changed content requires revalidation, never raw-body mirroring; A→B→A approvals create fresh revisions and superseded My reports associations are cleared. Never mirror comments, raw evidence, arbitrary labels or direct private Forgejo links. Duplicate reports map to the same portal issue; My reports filters private account mappings, not public reporter identities. 6. Catalogue synchronization is independent of daily AI work: reconcile at least every minute, including closed issues, removals/holds and revoked publication; enforce signed-in access on every page/API and fail closed for missing/invalid/stale publication data. Proposed maximum publication authorization staleness is five minutes during Forgejo outages. Never use an upstream label query as the authorization check. Only the new configured curated repositories feed this catalogue. General known issues are visible to signed-in portal users; Spiritech known issues require the portal client's spiritech_beta role. Legacy trackers remain excluded. Apply product/audience checks in database queries, page/API authorization, search/counts/filter options, My reports, caches, duplicate links and every downloadable resource; never fetch beta data and rely on client-side filtering. 7. Dedicated repo-restricted service tokens: portal delivery can write intake and read curated issues, executor can write only intake/curated issue metadata, code prefetch uses read-only repository credentials, and catalogue sync uses read access. Narrow bot membership as well as token scope. Do not use personal admin tokens or Forms__ReadApiToken in production. Pi receives none of these write credentials. Keep live player data out of Actions logs/artifacts; store bounded protected audit records. Initial deployment of volume/scanner/secrets/config may require full deployment under existing scope rules; subsequent portal-only code can use existing portal rollout. Verified planning evidence (2026-10-17; no production mutations): - Clean engines working tree before/after inspection. Installed live Forgejo /version and Swagger both report 15.0.9+gitea-1.22.0. Live attachment settings: enabled, five files per upload, MAX_SIZE=2048 MB and extension allowlist; versioned Forgejo config reference confirms units. API paging cap is 50. Authenticated metadata reads show current account has repository administration, but no production service tokens were created. - Live anonymous prk/issues metadata GET returns 200; private issues-private/triage-runner return 404. Two existing private attachment samples download with authenticated GET (200) and return 404 anonymously. HEAD returned 404 even authenticated, so HEAD is not a supported download authorization test. - A disposable local codeberg.org/forgejo/forgejo:15.0.9 container verified private issue creation, labels/comments, repo-restricted PAT allowing two selected repositories while denying an unrelated one, native .log upload/download with checksum equality and anonymous 404, unsupported .prkprobe rejection (422), .zip envelope acceptance (201) with preserved original bytes, and canonical issue creation in another private repository. Synthetic scratch repositories/container/anonymous volumes were removed; no tests wrote to production. - Exact marker reconciliation through paginated issue listing worked. Immediate q search did not find the newly created marker. A nonexistent label filter returned the existing issue rather than an empty result. These are explicit regression cases for delivery and publication authorization. No CAS/conditional update or API idempotency guarantee is assumed from Swagger. - Existing org runners expose the docker label and are visible as idle. Triage schedule has four recorded timer-triggered runs, all failed immediately; repository/org secret-name lists and repository variable-name list are empty. Timer firing is verified, successful execution is not. Failure root cause was not established from exposed API data; do not claim it was missing credentials alone. No workflow was dispatched and no deployed beta behavior changed. - Local Pi 1.3.0 SDK smoke test passed twice with openai-codex/gpt-6.1-sol and only a synthetic JSON prompt, no player reports or source code sent. OAuth readiness check succeeded without refreshing stored credentials; probe used a mode-0600 temporary copy limited to that provider and removed it afterwards. Main auth/config was not changed. - Portal anonymous home returns 200 and an existing protected route redirects to login. New feature and authenticated real-browser behavior do not exist yet and were not tested. Portal regression patterns and migrator/deployment configuration were inspected; no unchanged full engine build/test was run for this plan. - Remote content snapshots and disposable probe scripts/results are under /tmp/prk-bug-planning, not repository deliverables. Brave search unavailable; versioned Forgejo documentation was fetched directly. Initial default-port Git SSH failed and Ithaca probe timed out; user subsequently authorized another SSH verification round, which succeeded using the correct host endpoints. Git server is reachable through git-prk-server (root, port 2142); actual Ithaca through root@ithaca.project-rk.com (10.144.92.85). The configured ithaca user alias has a missing identity file; skyshard3 is a different proxy host, not Ithaca. No SSH configuration, production files, containers or services were changed. - Git-host SSH verified approximately 112 GiB free on its 413 GiB root filesystem, 58 GiB available RAM, Docker/systemd present, host Node v18.19.1. Pi requires Node >=22.19, so use a pinned Node 22.19+ worker container rather than host Node. Forgejo /data persists via /srv/forgejo/forgejo-data; attachment PATH is /data/gitea/attachments and that directory exists on the bind mount. Existing MinIO persists at /srv/minio, but its presence is not a reason to change the selected native Forgejo evidence design. No host clamscan/clamdscan or scanner service/container was found in checked locations. - Git-host Forgejo Nginx explicitly permits 300M request bodies, above proposed portal upload limits. Existing runner services 01/03/04 are running; runner-02 is in an auto-restart state. Do not infer the cause or repair it as part of this plan. Confirm a healthy assigned runner and actual job execution before rollout. Forgejo backup directory contains upgrade/theme-related snapshots, not demonstrated recurring full attachment/database coverage; no matching root backup cron or relevant backup timer was found in inspected locations. This does not prove no off-host backup exists. Backup observations are context only, not a new implementation or rollout gate. - Actual Ithaca SSH verified approximately 352 GiB free on its 914 GiB root filesystem and 45 GiB available RAM. Current portal is healthy but has ONLY the shared /root/GameData bind mount, with no dedicated persistent upload/quarantine path. Provision a portal-only staging volume; do not write uploaded files to GameData. No host scanner command or relevant scanner unit/container was found. Portal SITE_DB is empty and falls back to database IthacaDb (database name only inspected; no credentials printed). - Ithaca has a root SQL backup cron at 02:30 and a separate git-user SQL backup cron at 06:00. The root backup targets IthacaDb; its log was modified 2026-10-17T02:33:54Z and a bounded tail contains a completion/success indication. This is evidence of a configured/recently active SQL backup, not proof of a usable backup or restore. Inspected scripts do not mention attachment/staging paths and neither contained RESTORE VERIFYONLY. The second script includes a curl command; destination/coverage was not inferred. No backup/restore rehearsal or database rollback work is included in this feature. - Actual public portal edge is 5.161.243.214, prk-web-proxy-reverse-proxy-1 (Traefik v3.1), not skyshard3. Read-only SSH inspection found the portal route in /opt/prk-web-proxy/traefik.yml, with no explicit body-buffering/body-size/read/write/idle/response-header timeout directives in that mounted file or selected runtime flags. Do not assume unlimited uploads from absent overrides: configure and test intended size/time limits through actual edge, Ithaca ingress and Kestrel. Edge mount/config and runtime flags were inspected without exposing unrelated secrets. Git/Ithaca service ChatGPT credentials, OAuth refresh/restart behavior and model egress from the eventual isolated worker remain rollout tests, not verified by these host checks. Rollout gates, not unresolved architecture: verified host capacity is sufficient for the proposed initial limits, but enforce disk quotas and monitoring. Provision the missing portal-only staging volume and scanner accessory with bounded archive scanning and fail-closed health. Align portal edge/Ithaca ingress/Kestrel body and timeout limits and prove the maximum upload end-to-end; create bot accounts/repo-limited credentials and dedicated ChatGPT OAuth state; verify service restart/refresh and supported model on runner; configure workflow secrets/image tag and perform manual dry-run plus successful timer run. Create the fresh private intake, general curated, Spiritech curated and worker repositories with staff/service access only; enable new reports through the portal without modifying the legacy trackers. Do not migrate/backfill old issues as part of launch. Keep receipt/delivery retry available on provider outage and provide kill switches for AI writes/publication. Final acceptance still requires portal/worker regression tests, SQL crash/race tests, sandbox contract tests, injected hostile-file/model-output cases, authenticated browser flow. Deployment/cutover rehearsals and database rollback strategies are out of scope. Implementation milestone: portal foundation is built on feature/player-bug-reporting in engines, uncommitted and not deployed. Added Bugs domain/services and additive 003 migration, shared issuer/subject identity helper preserving forms keys, exact portal-client spiritech_beta authorization with a 15-minute validated-login stamp, authenticated Razor catalogue/submission/owner-only receipt, explicit cookie-only streaming upload API with antiforgery, immutable/idempotent Pending report records, SQL account-serialized quota/file association, owner-only 0700/0600 staging, fail-closed ClamAV INSTREAM adapter, fair failed-scan rotation and retryable unsubmitted-file expiry. Catalogue primitives enforce product/account filters, explicit publication/hash integrity and five-minute freshness. Attachment limits are configurable downward from 5 files/25 MiB each/100 MiB total; daily quotas configurable. Added no-file and partial-upload JS handling, retained-size accounting and clear-attachments control; CI runs the dependency-free Node UI tests. README explicitly documents partial scope and disabled default; no test sign-in endpoints or fixtures are in production source. Verified foundation: portal build with warnings-as-errors succeeds, zero warnings/errors. Focused PlayerPortal suite passes 73/73 with zero skips using disposable local MSSQL, including schema initialization/adoption, simultaneous submission retries, attachment reuse/quota races, catalogue SQL translations, real Razor/cookie/CSRF HTTP flows, role scope/lifetime, file boundaries, permissions, scanner protocol/truncated verdicts and cleanup/scan retry regressions. Five Node UI tests pass, including native-submit reentrancy and aggregate retained bytes after partial failure. Existing 23 offline deployment regressions pass; git diff --check passes. Browser acceptance initially exposed the no-file submit reentrancy bug, now fixed and retested successfully through the browser tool. Additional real Chrome/Playwright test with synthetic .log and arbitrary-extension files saw three 201 uploads across General and Spiritech, successful receipts and 404 when an ordinary player requested the beta receipt. Browser authentication and scanner were synthetic; no real player data, OIDC login, live ClamAV or Forgejo report writes were exercised. Local browser harness/code/results live only in ignored .dev-data/bug-reporting. Two static feature reviews found material issues (scan starvation, cleanup record deletion ordering, Unicode body capacity, Unix permissions, OIDC redirect versus API 401, retained upload aggregate sizing); fixes have regression coverage. First review had generated binary artifact gaps, later removed; no post-fix approval is claimed. Implementation is now complete and verified locally across both repositories. Added the private typed Forgejo client, durable issue/file attempted-write reconciliation and checksum-verified native/ZIP evidence transport; worker API with lease-scoped evidence and strict proposal validation; separate terminal/successful decision state; revision-bound publication manifests and independent withdrawal/freshness sync; and numeric-ID-allowlisted staff approval commands inside Forgejo. Repository-selected Forgejo PATs cannot include user scopes or query other users' repository permissions, so BotUserId and StaffUserIds are trusted operator configuration rather than granting broader lookup/admin credentials. All four service tokens must be distinct. Pending scans are excluded from delivery batches. Added migrations 004 and 005 without changing previously applied scripts. Production UI/integration/automatic-publication flags remain off by default. User authorized committing/pushing the worker and opening an engines PR. Worker initial commit efb1ea23af9ab438639966f7381b8319cb04043c (feature: Add code-aware player reporting worker) is pushed to private prk/player-reporting-worker on main and feature/player-reporting-worker; remote default verified main. The already-created empty intended repository was reused, not duplicated. User subsequently authorized rewriting all worker history to match the engines identity exactly: author and committer Unknown <unknown@noreply.git.project-rk.com>. The sole root commit was amended and both worker main/feature refs atomically force-with-lease pushed from d979f07 to efb1ea2; remote refs verified, Git tree unchanged, repo-local future identity configured, working tree clean. Engines history was not changed; PR2705 worker reference was updated. Unreachable server objects/CI caches were not purged. Worker scheduled job is gated by REPORTING_WORKER_ENABLED=true; no variables are configured, so publishing does not activate production triage. Engine commit a9728dd850a97afda6992ec121a1c3d1827a3d11 (feature: Add player bug reporting and private triage integration) is pushed on feature/player-bug-reporting, rebased cleanly onto origin/develop 9c092cd509c29790485d048e78212224655296f6 while retaining new CI behavior. Open PR2705 targeting develop: https://git.project-rk.com/prk/engines/pulls/2705 . Verified open and mergeable, no conflicts. Both working trees clean. Only 59 intended engine files and 44 worker files committed; ignored .local/.dev-data/auth/runtime data excluded and staged contents scanned against known local/provider credentials with no matches. Controller has only portal/analyzer credentials, model service has only its dedicated OAuth copy and read-only filtered/checksummed code. Separate containers, no Docker socket/shell/project extensions or skills in analysis, no write tokens in the model. Model input uses bounded/redacted text and resized screenshots; unsupported files are withheld from interpretation. Analysis has 150s wall time, 32 code calls, 32768 visible-output characters and an 8192-output-token budget checked between turns; Codex does not supply a hard server-side output cap, which is explicitly documented. Proposals must cite lines actually read. Both General and Spiritech use the same pipeline and immutable product routing. Final verified results: 88/88 focused PlayerPortal tests, zero skips, including actual disposable MSSQL schema/races and rejected replacement manifests, A→B→A publication, review label retries (including exhausted claims), cleared duplicate associations, pending-scan starvation and legacy identity literal compatibility. Portal warnings-as-errors build succeeds with zero warnings/errors. Five Node UI regressions, five TypeScript worker tests and 23 offline deployment regressions pass. Worker workflow actionlint passes (docker runner label exclusion), shell/Python checks and both Compose configurations validate; systemd calendar parses as 03:00 UTC. Static engine-patch review after fixes found no actionable findings; it did not execute tests and could not inspect the separate worker repository. Preserve that external-review limitation; worker compatibility is verified by actual cross-repository tests and manual boundary inspection, not claimed subagent approval. Full-stack Docker Compose is running locally under project prk-reporting-local, separate SQL/Forgejo/Keycloak/ClamAV/portal/analyzer/controller services and private volumes. Final endpoint checks return portal/Forgejo HTTP 200, scanner healthy, fixture analyzer active, no unexpected recent portal failures and no temporary model credential. PORTAL_COOKIE_NAME isolates this stack's auth/antiforgery cookies from the unrelated portal already running on localhost:5200; defaults remain unchanged in production. Final rebuilt-program OIDC/file/outage/revocation tests pass after this isolation change. Portal http://localhost:5520; Forgejo http://localhost:5530; real local Keycloak at http://id.prk.localhost:58080. Repeat with /home/mathias/Projects/player-reporting-worker/local/test.sh. Eleven real-Chrome full-stack checks pass: real OIDC; wrong-client/beta/worker denial; scanned PNG/log/arbitrary file handling; ZIP byte/hash preservation and private download; pending receipt privacy/restart; nonmutating dry-run; general publication/My reports; beta-only publication; duplicates without canonical re-creation; staff approval; withdrawal; Forgejo outage plus portal restart recovery without duplicate intake; fresh login after beta group removal (old-cookie expiry separately unit-tested at 15min); and EICAR quarantine. Scanner is the real ClamAV engine with a synthetic local signature database, not production malware coverage. Fixture analyzer is explicitly test-only and restored after live proofs. Real live ChatGPT/Pi test also passed after final changes: a synthetic report and screenshot submitted through actual local OIDC, scanned/delivered and interpreted through the real analyzer; model openai-codex/gpt-6.1-sol returned uncertain for a verification/non-defect report and cited five inspected source locations with snapshot provenance. Temporary OAuth copy was removed, original auth/config unchanged. Reproduce with local/live-check.sh; it restores fixture services and removes credentials on exit. Browser tool independently verified real OIDC UI/receipts/audience denial, with explicit limitation that its smoke used the fixture analyzer and did not repeat file tests. Results/screenshots/logs live only in ignored .local/results and .dev-data/bug-reporting. No real player or production data used. Local manual-use regression resolved: intake #34 (1bc124e8-911d-4e05-a014-e408f4550ba8) had been consumed by the fixture daemon and marked complete two seconds after submission; live-check.sh skipped the existing decision and tested a synthetic report. The suggested command was wrong for manual tickets. Added staff-authorized re-triage protocol (marker prk-portal-retriage:v1 + triage:requested), migration006 NeedsAnalysis, targeted claim/preview API filtering without fallback, archival attempt-specific audits and preservation of original payload/canonical attempted-create safety. Previous publication is invalidated and stale analysis-state labels cleared without deleting content. Added local/run-live.sh supporting --issue, --report-id, --retriage and --dry-run; it creates no synthetic tickets and waits for the targeted terminal audit. live-check.sh now targets only its self-test. Shared live setup copies only OAuth temporarily and leaves fixture worker stopped. All local commands share a host lock. Fixture safety corrected: test workers are profile-gated and constrained to an atomic allowlist of only IDs created by the E2E run; configured/file/CLI selections intersect and cannot broaden it. Fixtures cannot silently claim manual reports even during testing. Test and live cleanup leave the daemon stopped; corrected Docker Compose stopped-container recreation to use up --no-start --no-deps rather than unsupported create --no-deps. Controller logs proposal acceptance rather than claiming application success, rejects unknown CLI flags and does not swallow 409 as success. Actually reprocessed #34 with real ChatGPT/Pi via ./local/run-live.sh --issue 34 --retriage. Real audit comment236 records uncertain, area/client, confidence0.3, five inspected source references; the issue is now triage:needs-staff-review with fixture triage:complete removed. Reason: NPC identity, client details, precise reproduction and visual evidence are missing; inspected conversation code does not establish a black-rendering cause or a matching duplicate. Original report and original fixture audit222 remain preserved; no synthetic result was passed off as the real analysis. Provider copy removed and fixture worker idle after completion. Validation after correction:90/90 focused portal/real-disposable-SQL tests pass, including re-triage history/publishing invalidation and exact target/no-fallback regressions; seven worker TypeScript tests cover fixture selection, empty allowlists, later selected IDs and invalid arguments. Full eleven-check Compose/real-OIDC/Forgejo/ClamAV/browser suite passes with isolated selections and daemon stopped afterward. Targeted engine feature re-review found no actionable findings (static only; separate worker repository remained outside its snapshot). Production untouched and changes remain uncommitted. User requested less bot clutter and readable Forgejo formatting. Implemented shared presentation helpers for intake sections, readable triage recommendations/classification/assessment, collapsed code provenance and machine data, and collapsed prior assessments. Technical payloads/markers are preserved verbatim; reader supports both legacy raw JSON and formatted envelopes. Duplicate archive comments are skipped if the same payload is already recorded under legacy or current markers. Curated correlation hashes are hidden rather than printed as visible text; new publication comments are concise with collapsed data. Publication comments remain immutable (not edited by the formatter), including timestamp/ownership/revision checks. Applied a coordinated one-off cleanup to existing local #34: six comments preserved, audit JSON unchanged and staff comments identical. Latest live assessment281 stays expanded, prior real/fixture assessments collapsed with explicit fixture labels. Original report text/JSON retained in readable sections + collapsed snapshot. Chrome verified desktop1440/mobile390 rendering and disclosure behavior; browser had no independent historical baseline, but separate API before/after assertions verified preservation. Snapshot hashes and compact machine JSON are hidden by default. Safety review found that a formatter could invalidate an unapplied accepted decision, and then that GET-before-PATCH cannot exclude a racing direct Forgejo edit. Verified actual installed Forgejo endpoints ignore intentionally stale If-Match/If-Unmodified-Since headers (scratch local capability probe issue48, no portal marker; no real data touched). Therefore removed ALL new issue/comment rewrite methods, background collapsing, formatting endpoint/service and CLI rather than claim unsafe concurrency guarantees. Future output is append-only: readable new report sections and compact new assessments with collapsed reasoning/references/data; old posts are not rewritten. Duplicate archive suppression and legacy payload compatibility remain. The already verified one-off #34 cleanup is retained, not reverted. Existing-content formatting is not a supported ongoing API operation. Formatting changes remain uncommitted and production untouched. Final formatting validation:94/94 focused portal/actual disposable SQL tests pass, including layout/exact payload/legacy compatibility, publication handling, no duplicate archives and unchanged older human-noted content. Eight worker/local-parser tests pass. All eleven full-stack Compose/real-OIDC/Forgejo/ClamAV/browser checks pass after removal of rewrite code. Portal warnings-as-errors build passed. Scoped reviews identified the unsafe rewrite paths; these have been removed entirely, with no PATCH issue/comment surface remaining. Reviews were static and did not inspect the external worker repository or execute tests; do not claim independent full worker approval. Browser rendering and before/after #34 preservation were separately verified. Production configuration authorized by user (Ithaca portal, Git-host worker; secrets supplied through runner). Rechecked clean repositories and PR2705 still open. Confirmed current portal root user, only GameData mount and kamal Docker network; hosts have sufficient capacity. Created dedicated restricted Forgejo account portal-reporting-bot ID817, granted collaboration only on three fresh private reporting trackers, generated three repository-selected PATs plus separate worker/analyzer tokens. Allowed staff IDs derived from human Owners/Developers (not prk-system automation). Secrets retained only in mode0600 ignored .dev-data/reporting-deployment/production-private.json; never printed. Prepared disabled portal runtime JSON and worker config. No production feature or scheduler enabled. Local deployment wiring prepared but uncommitted: Ithaca-only portal config/upload/key bind mounts and environment paths; extended actual Kamal2.12 regression checks confirm no leakage into Ergo/non-portal roles. Ruby Kamal checks and23 deployment regressions pass. Added production scanner Compose definition in worker checkout (full clamav1.4.3 with persistent official signatures/FreshClam, private kamal network, no published port, bounded scan/stream resources and4GiB memory), not local synthetic signatures. SSH authorization restored on user continuation; reusable host connections allowed provisioning. Installed disabled portal runtime JSON and private upload/key directories on Ithaca under /srv/prk-reporting (directories0700, private config0600). Copied existing portal Data Protection key files into the persistent keys directory without displaying contents; new explicit application discriminator may still require fresh sign-in. Started private prk-reporting-scanner, no published ports, persistent official signatures and FreshClam12 checks/day. Healthy, loaded daily28156 and3628169 signatures after explicit first-update reload. Real INSTREAM clean/EICAR verdicts verified. Reporting, Forgejo integration and automatic publication confirmed false. Existing portal/game engines were not restarted. Git host: installed worker efb1ea2 at /opt/player-reporting-worker, cloned production engines main35d4939f0 under /srv/prk-reporting/source/engines, prepared4912 filtered/checksummed files. Explicit upload-pack safe-directory configuration fixes root clones/fetches without global trust; both fetch dry-runs pass. Built analyzer/controller images and started analyzer. Its health correctly returns503 until dedicated OAuth is supplied. Installed private controller/analyzer config files0600 UID1000, model-auth directory0700 UID1000, path env0600 root. Installed systemd units but timer remains disabled/inactive; Actions triage gate remains unset. Choose one scheduler before activation. Installed two distinct new forced-command/restrict SSH keys on Git host, preserving all existing keys: triage wrapper and configure-auth wrapper. Set private worker repository Actions secrets WORKER_SSH_KEY, WORKER_AUTH_SSH_KEY, WORKER_SSH_TARGET, WORKER_HOST_KEY from locally generated dedicated keys and host key obtained through verified SSH. Raw private keys never printed. Real SSH tests prove both keys reject arbitrary commands; configure-auth rejects malformed JSON without creating credentials. Wrapper accepts only configure-auth, holds the triage host lock, invokes fixed-path strict bounded provider-only OAuth installer, atomically writes0600 UID1000 auth.json, recreates analyzer and checks credential/source readiness (NOT live provider validity). Local and installed helper SHA256 hashes match. Public edge: added upload-only HTTPS router/middleware/service/transport under /opt/prk-web-proxy/traefik.yml on5.161.243.214. Existing unrelated YAML semantics preserved and proxy loaded change without restart. Exact25MiB cap,1MiB memory buffering, dial10s/header120s/idle180s backend bounds; existing public entrypoint read deadline60s verified from installed Traefik help. Synthetic25MiB body reaches current app404;25MiB+1 returns413 with Expect100-continue and access-log confirmation. Python send-all initially saw early connection reset on oversized body; curl verified actual413, not inferred. Public portal still200. This is transport verification, NOT authenticated submission against the unreleased portal. Live PAT verification: token registry confirms exact selected repos/scopes. Issue reads allow intended intake/curated repositories and deny unrelated/legacy repositories with404. Initial GET repository-metadata probe returned200 outside token selection; this endpoint is not a reliable issue-scope check. No production issues/test evidence were created, credentials did not need reissuing, legacy trackers untouched. User explicitly authorized committing/pushing deployment changes and running the authentication workflow, with a hard constraint not to restart main game servers. Revalidated10 worker tests,23 deployment regressions, real Kamal isolation checks, shell syntax, all3 workflows with pinned actionlint and staged credential scan; all pass. Committed/pushed engines9cf3fa952 (build: Configure private portal reporting storage on Ithaca) to feature/player-bug-reporting only; no develop/main engine push or deployment. Committed worker8fe4012 (build: Configure reporting authentication and production scanner), plus documentation correction0df4f3c, atomically fast-forward pushed both worker main/feature refs. All author/committer identities Unknown <unknown@noreply.git.project-rk.com>. Working trees clean. Worker code CI at8fe4012 passed; latest engine9cf3fa952 checks are pending, not successful yet. Fast-forwarded Git-host worker checkout to0df4f3c under host lock after verifying already-installed untracked helper contents match incoming files; host checkout clean. Private runtime/auth data remains ignored. Credential installation resolved after user replaced secret using the explicit openai-codex login and requested retry. Manual configure-auth run6 (API id5009, https://git.project-rk.com/prk/player-reporting-worker/actions/runs/6) succeeded. Verified private auth.json installed0600 UID/GID1000 and analyzer HTTP health200 after workflow recreated only the reporting analyzer. No token contents read or printed. Systemd reporting timer remains disabled; no game deployment/restart commands invoked. Subsequently, user authorized one synthetic live model probe on the Git-host reporting analyzer. Real POST /analyze under the same host flock returned200 in6968ms with configured openai-codex/gpt-6.1-sol. Supplied only a synthetic expected-behavior report about repeat portal form submission, no player data/files/candidates or portal/Forgejo writes. Production source snapshot35d4939f0081210daaaf7434c2ac009a81a5f02b:010260e5eb847f61a4222f549101aa0829c9b134c6d2eb5b5c495c8067803e72. Typed proposal validation and analyzer's read-reference verification succeeded; output is uncertain/area-portal/priority4, correctly states no defect established, and cites4 inspected FormService.cs locations (12,70,71,78). Source snapshot provenance prefix validated by probe. This establishes actual service-account/model access, code tool use and contract output, not just credential presence. Post-probe health200; OAuth remains0600 UID1000; timer disabled and Actions gate unset. Result retained only in ignored .dev-data/reporting-deployment/model-probe.json. No main game server deployment/restart, issue creation or scheduled processing invoked. Provider refresh/restart lifecycle and full released portal pipeline remain unverified. The earlier failed run4 correctly rejected the distinct openai OAuth flow without installing credentials. Pi has two different ChatGPT login flows; README correction remains relevant. CLI dispatch still reports unexpected end of JSON input even when creating the run; verified the single new run rather than blindly retrying. Safety verified: compared all six live Ithaca Login/Chat/Playfield container IDs, StartedAt values and restart counts before/after operations; every field unchanged. No portal/game deployment or server restart invoked. Only worker repository was advanced on main, triggering unit CI; engine pushes stayed on feature branch. Systemd timer disabled/inactive, Actions gate variable unset, reporting and automatic publication still disabled. No real production player report was analyzed; only an isolated synthetic model probe was run. PR2705 remains open; earlier engine CI failed and latest updated-head checks are pending, root cause uninvestigated. Do not claim launch readiness. Remaining activation work: obtain passing engine CI and investigate failures if they persist; complete authenticated production General/Spiritech/report-upload validation with reporting/Forgejo now enabled; retain explicit portal/main versus unchanged game-engine source provenance; verify expired-token OAuth refresh, authenticated production submission/role isolation and manual/scheduled execution; enable exactly one scheduler only after verification. Infrastructure/configuration is provisioned, but no reporting feature or automatic publication is enabled. Release integration: user confirms PR2705 green and merged; fetched origin/develop5c5cd98b0 (squashed reporting PR), origin/main35d4939f0. Promotion PR2708 is open, head develop/base main, mergeable=false. Reproduced exactly3 conflicts by creating local fix/resolve-develop-main-conflicts at develop and merging main with --no-commit --no-ff. Resolved test-kamal-config.rb, engines-dotnet.yml and _Layout.cshtml by preserving develop's actual combined superset: reporting mount/isolation checks; newer prebuilt CI image/cache/sharded tests plus deployment/JS checks (no obsolete tool installation); conditional Known Issues link plus shared developer-inclusive Forms authorization. All3 resolved files exactly match develop. Auto-merged staged delta is solely6 production game-role command lines in config/deploy.ithaca.yml, preserving main's current5.161.243.214 IPs and login chat port7005 rather than develop's stale endpoints. Verified each of six role commands equals main. No unresolved files/markers remain. Validation of prepared merge:94 focused real-disposable-SQL portal tests,23 deployment regressions,5 UI tests, actual Kamal role isolation and actionlint pass. Portal warnings-as-errors build passes zero warnings/errors after isolating native build directory; initial plain build failed due stale host-path CMake cache, not source. Removed only new root-owned Avalonia build task artifacts created by container tests. User explicitly authorized commit/push of the conflict fix. Created merge commit433213bca7e4277b423708b6432f6a743c171dcb (fix: Resolve develop and main integration conflicts), author/committer Unknown <unknown@noreply.git.project-rk.com>, preserving parents5c5cd98b0 and35d4939f0. Pushed only refs/heads/fix/resolve-develop-main-conflicts and verified exact remote SHA; branch upstream now tracks that same fix branch, working tree clean. No develop/main push, PR creation/merge or deployment performed. Existing PR2708 is not remotely resolved until main ancestry reaches develop; preserve merge commit/no-squash when integrating this fix. User subsequently merged fixPR2709 into develop3ec958757 using a merge commit; main ancestry preserved and promotionPR2708 became mergeable. User merged2708 into main8983c62f4504121681d4fe317f4dd3f53235c024 and reports canceling automatic Ithaca deployment manually. Manual portal runs4911/4912 used develop and correctly failed production-branch guard before deployment. Correct main/portal run4913 (API5023) succeeded; no additional deployment was initiated by assistant. Post-release read-only checks: deployed portal container engines-portal-ithaca-8983c62... healthy, started2026-10-18T00:05:59Z, public homepage200. Actual configured health probe is homepage /; exploratory /health/ready returned404 because that endpoint does not exist, not a failed configured readiness check. Anonymous /Bugs redirects302 to sign-in. Verified portal runtime/key environment paths and exact portal-only bind mounts: config read-only, uploads/keys writable; in-container read/write permission tests pass. Private JSON flags reporting=false, Forgejo=false, automatic publication=false with no environment overrides. ClamAV healthy/no published port; PING succeeds from INSIDE deployed portal container, verifying Docker DNS/network reachability. Compared all6 live game containers with stored pre-release baseline: IDs, commands, StartedAt and restart counts all identical. No main game restart occurred. API listing showed no active/queued Ithaca deploy runs. No files/configs/services were changed during verification. User authorized controlled activation. Updated only BugReporting.Enabled and BugReporting.Forgejo.Enabled from false to true in Ithaca private runtime JSON, preserving the bind-mounted file inode, permissions0600 and all unrelated values. Automatic publication remains false. Restarted only exact portal container a8ec2194ac29 (image8983c62...), verified healthy. All six game server IDs/start times/restart counts match pre-release baseline. Post-restart incident: public homepage/worker endpoints returned plain Traefik404 while portal internal / and Ithaca host ingress returned200. Fresh HTTP connections from edge host AND inside public web proxy also reached backend200; the separately transported upload route returned401 while the regular player-portal transport stayed404. This supports stale pooled connections accepted by Ithaca fallback HTTP handler during portal health transition, not an application failure. No source/edge routing edits applied. User explicitly permitted a Traefik restart. Restarted ONLY public web proxy prk-web-proxy-reverse-proxy-1 on5.161.243.214 at2026-10-18T09:13:40Z, after confirming command entrypoints80/443 (container uses host networking, so PortBindings empty). Did NOT restart shared Ithaca game-traffic Traefik. Public homepage immediately200, /Bugs302 to sign-in, unauthenticated worker preview401 and unauthenticated uploads401. Authenticated read-only worker preview204 verifies enabled worker authentication and live SQL path with empty queue. Portal and scanner healthy; no Bug reporting phase errors in selected last10min logs. All6 game containers again exactly unchanged. Systemd reporting timer inactive/disabled; Actions gate remains unset. Reporting is now live for controlled authenticated player testing, not full launch acceptance. First user attempt was a stale browser session redirected to login and created no intake report. After fresh sign-in and resubmission, verified first real production intake issue#1 created2026-10-18T09:21:51Z in private player-bug-intake, with triage:ready and1 delivered attachment; no delivery/scanner/phase warnings in selected logs. Initial immediate issue listing was empty; next30-second polling cycle showed successful delivery, consistent with configured background polling. Ready label indicates delivery passed clean-file/checksum workflow rather than quarantine. User then authorized source refresh and manual triage. Under shared nonblocking host lock, fast-forwarded clean Git-host source checkout to deployed portal/main8983c62f4504121681d4fe317f4dd3f53235c024, generated4988 allowlisted/checksummed source files (snapshot suffix86ecf49ab9cbdb017fe140f129d1c221d11d01f5663ee1b8a25ad6c3bc6c970a), recreated ONLY reporting analyzer so replaced bind mount is visible, and verified readiness. Correlated intake#1 marker to reporta4b59cb9-0b3d-441d-9b9e-33703da69bdd via targeted read-only preview. Ran real controller with --report-id for that UUID only, not unrestricted batch. It processed exactly1 job with1 clean evidence file; real ChatGPT/Pi proposal accepted. Verified subsequent executor outcome on private intake#1: bot audit comment37150 contains uncertain/area-client/priority3/confidence0.45, with2 inspected references to PRK.Client/PRK.Client.Tests/UiPresenterTests.cs lines337 and342. Assessment: character can appear partially rendered/missing head during world entry; tests support expected loading screen during Connecting/EnteringWorld but do not prove asset-readiness behavior or cause. Attached video is retained evidence but withheld from model interpretation by current supported-type policy, explicitly disclosed in assessment. No verified fix or reproduction claimed. Intake now has triage:needs-staff-review (triage:ready also remains per current additive label behavior). Both curated trackers still have0 issues; automatic publication=false. Original report/asset preserved, no staff content rewritten. Credential metadata check around run: expiredBefore=false, expiryAdvanced=false, validExpiryAfter=true; OAuth remains0600 UID1000. Thus persistent auth survives analyzer recreation and actual model invocation, but automatic expired-token refresh has NOT yet been exercised. Timer remains disabled; all6 game-server starts still2026-10-16T21:* with restartCount0, no main game/proxy/portal restarts in this operation. Both working trees clean. Results kept only in ignored deployment artifacts. This proves production General submission/evidence/private delivery/model proposal/executor review end-to-end, not Spiritech isolation, publication/withdrawal or scheduled execution. User challenged weak triage and clarified the test report concerns Spiritech but was submitted as General. IMPORTANT CORRECTION: user explicitly identifies Spiritech as PRK.Client/ in engines. Assistant incorrectly inferred from existence of a separate prk/spiritech repository that the relevant source was missing. Retract that inference: the worker DOES already have the correct Spiritech source in its engines snapshot; do not add another repository or product-to-repo routing based on that mistake. Product currently controls prompt context, same-product duplicate candidates and curated destination/access; selecting General did not remove PRK.Client source access. Confirmed evidence limitation remains: src/evidence.ts interprets only allowlisted text/still images, so video was stored/scanned but withheld from model interpretation. Final assessment cited only two PRK.Client UI-test lines, not an established investigation of the rendering/loading implementation or verified cause. Pipeline success does NOT establish adequate triage quality. User authorized better prompting/more searching and explicit Spiritech=>likely PRK.Client investigation context. Implemented locally in worker branch fix/improve-triage-investigation; no commits/push/deployment or production service restart. Video extraction remains outside this requested patch: still safely withheld, now explicitly not a reason to skip investigating written reproduction. Found real tooling limitations: listings silently truncated at200 paths and searches only covered first2000 selected files/50 hits. Added paginated case-insensitive filename discovery; bounded literal search pages with opaque session/selection-bound continuation cursors (same query/prefix/test setting), explicit completion/exclusion counts, resumable in-file hit/output limits, implementation-first search with deliberate includeTests, and existing checksum/traversal/symlink protections retained. Per-page resource bounds:2000 files,32MiB (+at most one bounded source file),50 hits and20K serialized hit-character budget. Increased code-call limit32->64; retained150s wall deadline,32768 streamed characters and8192 output tokens; switched reasoning low->medium. Extracted typed prompt/context helpers: Spiritech starts in PRK.Client, cross-boundary server/shared investigation remains possible; General is not server-only and written client context can guide searches without changing immutable audience/destinations. Prompt asks for concrete production call/state tracing, alternative explanations, actionable uncertainty/next checks, limits/withheld-evidence disclosure and test assertions only as supporting evidence. Known-defect proposals now require an actually read non-test implementation reference; private provenance includes search and distinct read_code file counts (not files merely scanned/listed). No output contract, server-side permission or publication-policy changes. Red-green validation:4 new core regressions initially failed against old tools; final18 tests all pass, including reaching implementation after old2000-file cutoff, filename/list pagination, exact within-file continuation, selection-bound cursors, escaped output bounds, test classification edge cases, inspected-only/implementation citation guards and Spiritech/General audience context. TypeScript build and git diff --check pass. Real local snapshot EnteringWorld search inspected836 eligible files, excluded471 test files and found production Screen/ScreenDerivation/Skybox/CharacterSelectionScene/ClientUiCoordinator candidates rather than only UI tests. User explicitly authorized commit/push, worker-only deployment, fresh triage and removal of previous bot result. Pushed e3a00b0 (fix: Deepen triage investigation and source discovery) and follow-up4ce3dee (build: Include deployment test prerequisites in worker image) atomically to worker main/fix-improve-triage-investigation refs. First production image build caught2 deployment tests failing because Docker build stage lacked Python and deploy/install-model-auth.py; fixed build-stage prerequisites/copy without adding Python to runtime, validated complete local Docker image build, then built/deployed analyzer/controller on Git host under the host lock. Only reporting analyzer recreated; worker at4ce3dee, checkout clean. Both remote worker CI runs8/9 passed. No engines repo changes, portal/shared-proxy/game restarts or scheduling enablement. One-off fresh-slate handling: captured old bot assessment37150 plus original report/asset metadata privately0600 in ignored deployment artifacts; verified bot817 ownership, original unedited timestamps and unchanged body hash before deletion. Posted trusted staff retriage command37152 (operator allowlisted) clarifying this is Spiritech/PRK.Client despite intentionally retained General test audience. Added triage:requested, waited for targeted preview200 with clarification/unchanged General audience so supported archive/state invalidation completed while original bot audit still existed. Removed ONLY old bot assessment37150 by explicit user authorization, outside model capabilities. Verified original issue title/body hash and attachment id/uuid/name/size unchanged, staff clarification preserved. Model toolset remains strictly read-only and no runtime delete API was introduced. Ran controller only for reporta4b59cb9-0b3d-441d-9b9e-33703da69bdd; exactly1 proposal accepted, executor posted fresh bot assessment37155. Latest issue comments contain37152/37155, not37150. New model performed13 searches and read17 distinct implementation files, citing12 relevant production locations across ConnectionFlow, ScreenDerivation, ClientUiCoordinator, network/full-character/appearance handling, CharacterSelectionScene, CharacterVisualProvider and AnimatedRenderable. Assessment uncertain/area-client/priority3/confidence0.65: traced FullCharacterMessage=>InPlay=>loading dismissal without explicit visual readiness, but identified renderer waiting for registered mesh/material/attachment dependencies as counterevidence to simplistic slow head upload explanation; competing missing/failed head construction or preview-to-world handoff remains. Gives concrete cold/warm-cache, preview-vs-world, packet/state/attachment-readiness checks. No verified root cause claimed; video still withheld explicitly. Both curated trackers remain0 issues, automatic publication false, systemd timer disabled. All6 game servers retain original2026-10-16T21:* starts and restartCount0. Both local repos clean. After user installed new remote_python tool, all further server work must use that tool exclusively as requested. New-tool smoke verified execution/cwd/stdout-stderr, local syntax rejection and nonzero exit reporting. Latest read-only remote_python check confirms deployed4ce3dee, clean checkout, analyzer HTTP200, scheduler disabled, OAuth0600. Current quality patch is implemented/deployed/live-evaluated. User then reported production /Bugs/Submit/spiritech404, resolved by sign-out/sign-in. Source confirms deliberate hidden404 when exact portal-client beta claim/fresh15min authorization stamp is absent/expired; route itself exists. Live OIDC redirect names production client Portal (not local-test default PlayerPortal). Role-expiry UX should eventually reauthenticate/revalidate rather than look like a broken page, without extending stale beta privileges. After fresh login user submitted a Spiritech report. Read-only remote_python on configured git-prk-server used private controller credentials against production preview: HTTP200, reportf83dda1b-48a0-4a67-8912-fce19f97d2a1, product=spiritech,1 clean delivered evidence file,0 same-product candidates, candidatesTruncated=false, leaseToken=null. Preview did not claim/analyze/publish. User subsequently authorized targeted manual triage for f83dda1b-48a0-4a67-8912-fce19f97d2a1. Using remote_python exclusively, verified pending product=spiritech then ran one controller invocation under host flock with --report-id; exactly1 uncertain proposal was accepted. No service restart invoked. Final executor comment was not independently fetched before user feedback. User first considered staff review excessive, then clarified this test bug was already fixed, so it is not a reliable calibration case for detecting an obvious unfixed defect. Important policy distinction: AllowAutomaticPublication=false deliberately sends even confident known/duplicate automated proposals to staff review; the label alone does not measure analysis confidence/quality. Do not relax model thresholds based on this already-fixed test. User then submitted another report for calibration. After normal delivery-poll delay, read-only preview returned Spiritech report6fe9b43e-4804-4319-8962-4971411449b4 with5 clean delivered files and no lease. Ran only that report through controller under host flock using remote_python; exactly1 uncertain proposal accepted. Read current private intake through ordinary authenticated Forgejo issue API (no SSH/server-shell operations), matched exact marker to issue#3, and verified executor posted bot assessment37161 with triage:needs-staff-review. Result: terminal nameplates too high above usable body/near antenna tips, area/client, priority3, confidence0.84. Model reports all5 supplied images interpreted,6 searches and8 implementation files read. Traced picking/selected target, indicator anchors, placed-object mesh height and nameplate projection/clamping; concrete suspected mechanism is MeshTree.MeshHeight using twice largest triangle-mesh bounding-sphere radius rather than usable-body/vertical bounds, plus anchor padding/transform. Identified fallback sphere and origin/scale metadata as alternatives; no affected asset/runtime anchor data means exact cause unconfirmed. Gives reproducible position/camera/build/asset geometry checks. Ten production references recorded. Source snapshot remains8983c62...; no service restart, issue closure, implementation or publication requested/performed. Calibration note: current system prompt explicitly says only a demonstrated implementation defect supports known. This may conflate confirming an observable bug with proving its root cause; current report is useful evidence for considering that distinction, rather than merely lowering numerical confidence. No prompt/threshold/schema changes made in that run. User now explicitly clarifies intended product behavior: triage supplies a useful developer starting point, not proof of exact root cause; duplicate detection is the highest priority; staff capacity is limited and manual review must be very rare. Also check recent develop commits/merged work and open PRs so already-fixed or in-progress reports are recognized. This changes the intended calibration/workflow, not just wording. CURRENT IMPLEMENTED SCOPE (worker deployed; user promoted and portal-only deployed; live v2 handoff/development-context calibration passed): normal coherent reports should complete automated triage as new/actionable, duplicate, related to work in progress, or addressed in development, with evidence, concrete code entry points and verification gaps. Unknown root cause, need for reproduction, moderate confidence, withheld evidence or paused publication must not by themselves create staff-review work. Reserve review for genuinely consequential ambiguity/sensitive disclosure/unsafe target or conflicting human decisions; retry operational failures automatically where safe, preserving ambiguous-create protections. Keep original reports/evidence and human holds intact; do not automatically close/delete issues. Duplicate retrieval must cover same-audience fresh private intake AND curated issues, including pending/unpublished and closed/fixed cases, not only published catalogue snapshots. Current BugTriage only ranks up to50 candidates by title words from <=501 fresh published projections; current empty catalogues yield no candidates. Need broader bounded retrieval, explicit coverage and server-validated references, without cross-audience exposure. Preserve prior exclusion of legacy trackers unless user explicitly changes that scope. Existing-work context must include read-only recent develop history and open PR metadata/relevant changes at recorded refs; keep any read credential outside model sandbox. Distinguish matching existing bug from matching implementing PR, and merged-in-develop from actually released in the reporter's build. Link exact supplied PR/commit references privately; no invented references or unsupported claims that a fix is deployed. Deterministic gates must change with the prompt: BugProposal.CanPublishAutomatically currently requires>=0.85 plus source evidence and non-uncertain; BugExecutor turns paused automatic publication or those failed gates into needs-staff-review. Separate triage completion from publication pause instead of relabeling a mandatory manual queue. Model confidence should describe triage/duplicate recommendation, not verified runtime root cause. Preserve privacy/security validation and scoped executor. User authorized all rollout preparation except merging or deploying the portal. Committed/pushed engines5df2146ace4d544c92648fd7aa051180a9f78daa on fix/automate-report-triage only, opened PR2722 targeting develop (https://git.project-rk.com/prk/engines/pulls/2722), initially verified open/unmerged/mergeable; user subsequently merged PR2722 to develop3068eb7d9. Base develop advanced to d214b5ecc with no overlapping portal/config changes; branch remains based on2ef5dc10d and CI merges current base. Engine CI successful; client CI pending at final check. Committed worker853aa018390e7d7b794a5e774ad1e9b71c92ec39, atomically pushed worker main and fix/duplicate-first-triage; worker CI passed. Both identities Unknown <unknown@noreply.git.project-rk.com>; staged known-credential scans pass; both working trees clean. No engine develop/main push, portal merge or deployment. Additive migration007 introduces private duplicate parent/fingerprint, offered context JSON and publication-pending state; no old migration modified. Implementation: ordinary known means developer handoff, no confidence/evidence/root-cause proof gate; privacy/sensitivity/invalid-target protections remain. Paused publication completes triage privately and resumes eligible decisions when enabled instead of creating staff-review work. Duplicate search ranks complete eligible intake in SQL then authoritative Forgejo descriptions/human notes, combines closed/unpublished curated issues, excludes holds/self roots/canonical dependencies and enforces same-product earlier references. Saved fingerprints bind target content at claim/approval, execution and synchronization. Material drift automatically queues fresh analysis (retaining bounded retries) rather than routine review; deleted/unsafe targets remain exceptional conflicts. Both intake endpoints must retain markers and no holds before associations propagate; mappings withdraw safely, canonical dependency walk prevents forward/reverse alias cycles, explicit staff approval snapshots its target at command acceptance and is rechecked. Readable duplicate links are revision-scoped append-only. Automatic retries clear obsolete analysis labels using one shared allowlist. Development history: new default-disabled DevelopmentContextEnabled, SourceRepository fixed prk/engines, separate SourceReadToken. GET-only repository-bound requests, no redirects via existing client configuration; source credential never enters worker/model payload. Fetch pinned develop head/latest50 commits and up to50 open PRs; rank top8 and supply bounded summaries, files and raw diff excerpts (real installed API ChangedFile lacks patch field; corrected to .diff endpoints). Cap source lookup12s, diff read64KiB/excerpt3000chars; recheck PR head/state after fetching patch; disclose partial/unavailable context, including response-stream I/O failures, while preserving caller cancellation. Model selects only offered work keys; server adds exact private links/triage-work-in-progress or fix-in-development labels, never claims deploy/auto-closes. Worker duplicate-first prompt distinguishes reported bug from confirmed mechanism and existing PR from duplicate issue. Invalid model contracts/references/budget failures are retried as operational errors, not immediate model-declared staff review. Compatibility: new worker requests contractVersion=2, tolerates legacy jobs; new portal emits extended fields only for opt-in claims/previews while persisting offered targets internally for all versions. Optional proposal properties omit null to preserve existing serialized hashes. Worker-only first, then portal rollout is supported; publication/scheduling stay paused during rollout. Provisioned existing restricted portal-reporting-bot817 read collaboration on prk/engines and a NEW repo-selected PAT with only read:repository/read:issue for engines. Verified live develop-branch/open-PR/commit-diff/PR-diff reads and denied intake issue access; token never printed. Stored mode0600 in ignored private state and installed engines Actions secret REPORTING_SOURCE_READ_TOKEN. Added/tested Ithaca portal-only runner env/secret mapping (source lookup auto-enabled only when secret nonempty, fixed source repo, source token absent from Ergo/nonportal roles), workflow env passthrough, .kamal/secrets.ithaca reference and non-disclosing deployment-token preflight. Existing live portal config/process untouched; this wiring takes effect only on future user-approved portal rollout. Offline deployment suite now25 tests; real Kamal isolation checks pass both with/without source token. actionlint passes with narrow existing Forgejo URL-action/custom-runner exclusions. Verified final patch:116 focused portal tests pass with actual disposable local MSSQL, zero skips;21 worker tests pass;11 existing full local Compose/Chrome checks pass with actual OIDC/Forgejo/ClamAV plus explicit fixture analyzer, no production mutations. Portal warnings-as-errors build succeeds0warnings/errors;23 offline deployment regressions and5 UI tests pass; worker image builds through all tests. Added regressions for pending/private/closed duplicates, target edits/deletion/audience changes, ownership loss/holds, both alias orderings, staff-approved provenance races, retargeted audit links, refresh-label cleanup, source read-only/path bounds, PR revision drift, interrupted optional lookup, cancellation, SQL ranking-before-window and v1/v2 contracts. Private credential scans and diff checks pass. Container-generated Avalonia task artifacts removed. Temporary SQL runner now uses unique disposable test DB names; earlier3 failures were expected migration-hash refusal against a reused local draft DB, final fresh runs pass. Three static review rounds found material lifecycle issues, all addressed with regressions. Reviews did not execute tests or inspect separate worker repository; do not claim independent whole-worker approval or a no-findings final review after last corrections. Worker-only rollout completed using remote_python exclusively for server operations on configured git-prk-server. Under host flock, fast-forwarded clean worker checkout to853aa01, rebuilt analyzer/controller images (all21 tests), recreated ONLY reporting analyzer, verified new duplicate-first prompt and health200, clean checkout and disabled timer. Source snapshot deliberately unchanged until portal rollout; no portal/shared-proxy/game restart commands invoked. Read-only compatibility check from the new controller image requested contractVersion2 against still-old portal and received204 empty queue; no report claimed/analyzed/published. Actions triage gate remains unset, publication/scheduling remain off. Source credential/API permission verification complete; real new portal v2/development-context/model calibration remains pending portal merge/deploy, explicitly withheld per user. Full new duplicate search/review/publication behavior cannot be claimed live before that step. User additionally requested removing portal from Ergo deployment, since it is inaccessible/unconfigured there. Implemented a local follow-up on the same engines fix branch; not yet committed/pushed. Moved complete portal role from shared deploy.yml into deploy.ithaca.yml, preserving all Ithaca role/proxy/options/health/env/secret behavior exactly (deep-merged YAML before/after comparison equal). Removed Ergo portal override, 5051 publish and portal Traefik entrypoint; removed manual portal scope option from Ergo workflow. Shared deployment script rejects explicit Ergo portal scope before server commands, skips automatic portal-only updates when no engine update is needed, and performs portal container/public checks only on Ithaca. Full Ergo deployment still warns/deploys configured engine roles without any portal command. Updated native deployment docs and actual merged Kamal checks. Verified red-green: new/updated regressions initially produced3 expected failures against old deploy script. Final27 deployment tests pass; Kamal checks pass for Ergo without portal/ingress/secrets and Ithaca with all original portal wiring, with source token absent/present; both workflows lint with existing Forgejo action URL/runner exclusions; bash syntax and diff checks pass. This affects9 source files only, no C# runtime changes. No server commands, deployments, proxy restarts or live container removal performed. Any existing Ergo portal container is deliberately left untouched; removing an orphan service would be a separate authorized operation. User authorized pushing follow-up to PR2722. Committed eec55fee27d7761251c033660a32381e76c40a1e (fix: Remove the portal from Ergo deployments), pushed only fix/automate-report-triage and verified remote output links existing PR2722. Working tree clean; no develop/main push, PR merge or deployment. User subsequently merged PR2722 (including the Ergo follow-up) into develop3068eb7d9 at2026-10-18T12:54:46Z. Verified merged via gitea; latest develop engine/client CI and Ergo deployment checks are pending, not claimed green. User subsequently promoted/deployed the portal. Verified manual Ithaca run4974 success on mainc647731f62443441adbafb8d56e6d6312f75f860; workflow_dispatch event inputs explicitly scope=portal. Automatic run4972 for same commit was canceled. No promotion/deployment initiated by assistant. Read-only remote_python from Git host confirms public homepage200, authenticated preview contractVersion2 returns204 empty queue (new schema/query path healthy), unsupported version999 returns400 (new endpoint negotiation active). Worker systemd timer stilldisabled and Actions variable list empty. No report reprocessing or flag changes performed during verification. Development context and effective publication pause still need an actual pending v2 report/live calibration; do not infer successful source lookup from empty preview. Worker snapshot remains recorded prior source revision until an approved refresh; source branch/release provenance must remain explicit. User authorized controlled re-triage of pilot#3. Refreshed approved read-only source snapshot to deployed mainc647731f62443441adbafb8d56e6d6312f75f860: d6ff4b7ee78da709221699bf9c671512b48262f1242142f7e270df31c0055789 (5079 files), recreated only reporting analyzer using remote_python under host lock. Posted trusted staff re-triage comment37210, preserving old assessment37161. Verified live v2 preview on Spiritech report6fe9b43e-4804-4319-8962-4971411449b4:5 clean files,1 same-audience duplicate candidate, WorkContext.Available=true with pinned develop3068eb7d9 and relevant recent nameplate/headless-preview commits among8 bounded work items. Source-read secret/mapping/API therefore actually works; coverage limited is explicitly true. Targeted model batch failed before any new accepted/audited proposal. Analyzer logged generic analysis-failed; report became leased (preview204), old assessment untouched, no blind re-claim. Diagnosed exact boundary bug with actual context: source commit337d6b82 summary was1200 chars before redaction and1205 afterward; controller redacted new candidate/work fields without reclipping, violating analyzer schema before model execution. Reproduced using a controller-to-analyzer regression: old code failed1/22 tests, fixed code22/22 pass and Docker image build succeeds. Fixed candidate title/summary and source title/summary/patch bounds AFTER redaction; no review threshold change or larger data allowance. SSH signing blocker resolved after user explicitly requested retry. Atomically pushed worker0107a98253e45b68733fb097453d445f3c802a36 to main/fix-bound-redacted-triage-context via the configured agent, no identity/config/auth fallback. Deployed only analyzer/controller images on Git host using remote_python under shared flock; analyzer healthy200, worker checkout clean.22 local tests and Docker build pass; remote worker CI success. Report's old lease expired naturally; verified targeted preview200 before exactly one controlled retry, no forced database/reset/delivery manipulation. LIVE CALIBRATION PASSED: worker processed only Spiritech pilot#3/report6fe9b43e-4804-4319-8962-4971411449b4 and proposed known (developer handoff), not uncertain. Executor recorded new private bot assessment37213, preserved earlier37161, applied triage:complete and triage:fix-in-development, removed needs-staff-review, and created no curated issues (both trackers remain0). Thus routine triage completed while publication remains paused—no mandatory staff approval. All5 screenshots available;3 searches/4 implementation files read. Confidence0.97 refers to recommendation, not proven root cause. Correctly rejected the supplied character-selection candidate as unrelated to terminal nameplates. Referenced exact offered commits24747fe6586158ce05d73b35f0689540fbad6aa2 (#2697 object nameplate height/clamping) and650fe0e3209ce2dba38cb1bfd0c1dc1901b1f267 (#2716 screen-top plate sizing), with server-validated private links. Assessment distinguishes related existing fixes from duplicate bug targets, observes original commit already acknowledges tall bank mesh/ceiling occlusion, and does not claim those changes solve body-level placement or are in reporter's build. Gives concrete reproduction/build/ceiling-vs-screen-edge checks; exact cause remains a hypothesis without blocking completion. Artifacts in ignored .dev-data/reporting-deployment/pilot3-new-policy-result.json; no credentials printed. Source snapshot now matches deployed portal mainc647731f6 with pinned hash; development context pinned3068eb7d9 with explicit limited coverage. No portal/shared-proxy/game restart during calibration; only reporting analyzer was recreated for snapshot/fix rollout. Scheduler disabled and Actions triage variable unset; no publication flag change or model-driven issue closure. POSITIVE LIVE DUPLICATE TEST NOW PASSED. User explicitly requested full live duplicate testing. Used headed test_in_chrome with a fresh isolated profile and manual user Keycloak login (no credentials/cookie reuse/backdoors). Submitted exactly1 clearly marked Spiritech duplicate test with no new attachments, matching pilot#3's terminal-nameplate symptom but without exposing expected target ID/number in the form. Receipt1bdf76cd-3c40-4e30-99cb-cf08640d4e5d saved; browser saw Report received but numeric POST status was unavailable. Transient pre-login404 diagnostics occurred; authenticated form/submission succeeded. Production intake#4 was delivered. Read-only v2 preview verified productSpiritech,0files,2same-audience candidates including original report6fe9b43e.../intake#3 and live development context. Under host flock via remote_python ran only the new receipt; real model proposed duplicate with duplicateReportId pointing to original#3. Executor recorded bot assessment37219 and revision-scoped link37221 explicitly to intake#3. Verified triage:duplicate and NO needs-staff-review; issue stays open, no closure/deletion, both curated tracker counts remain0. Original#3 title/body hash and all5 asset id/uuid/name/size tuples match pre-test baseline. No staff approval required. Test report remains clearly marked and audited; it is not another canonical or a future root candidate. Artifacts ignored/private: live-duplicate-baseline.json and live-duplicate-result.json. No service restart/flag/scheduler change in this test. Remaining broader checks include expired-token refresh, controlled publication/withdrawal and chosen scheduler execution; no full launch completion claimed. User requested full repository cleanup and launch preparation. Both working trees clean; worker local checkout still on completed fix branch0107a98, no local main yet; engines on completed fix/automate-report-triage eec55fee2. Verified merged PRs2705/2709/2722 through gitea. Plan to return engines to develop/worker to main, remove only verified completed reporting branches (account for squash merges; unrelated branches/worktrees untouched), stop disposable local test stack without deleting volumes/manual#34, move active operational secrets and preserved test/report audit artifacts outside source checkouts into a0700 private operations directory, and assess remaining launch gates. Do NOT use broad git clean/docker prune, delete reports/evidence/test volumes or enable publication/scheduling as part of cleanup without validation. BLOCKER: configured SSH agent again failed signing Home PC during git fetch origin --prune, Permission denied publickey. Compound inventory command then timed out while the separate worker fetch was pending; treat its completion as unknown and inspect before retrying. No identity/config/agent changes, raw SSH/alternate auth fallback or automatic retry attempted. Asked user to unlock/approve configured agent and say retry; remote fetch/pruning/server work paused. No branches deleted, no services stopped and no launch flags changed yet. Completed safe local cleanup: removed413.4MiB of six redundant full Actions API metadata snapshots (each44–75MiB), retaining credentials, source/model/report/evidence baselines, operator audit history and a0600 concise launch-audit-summary.json. No report data or test volumes deleted. Initial .dev-data/reporting-deployment size419MiB mainly came from unbounded Actions API list responses; avoid saving full raw run lists again. Local worker.local46MiB and disposable test stack remain intact pending cleanup. CI finding: main validation run4973 was canceled BEFORE start; statuses labeled failure were misleading. This is absence of a clean main CI result, not evidence of a build/test regression. User subsequently explicitly requested full launch, with all pilot issues removed first. LAUNCH NOW ACTIVE (2026-10-18): removed all4 verified pre-launch intake issues1–4; General and Spiritech curated trackers remain empty. User explicitly clarified even genuine pilot#3 must be removed and real bugs will later be added/migrated from old tracker. Legacy trackers untouched; migration remains separate scope. Cleanup sequence preserved processing safety: privately exported all4 issue records, comments and downloaded original asset bytes with SHA256 into0700 ~/.local/share/prk-reporting-ops/pilot-retirement-20261018T155313Z (files0600). Posted one operator-authored retirement approval per exact pilot through supported staff flow; retirement proposals uncertain ensure durable decision Applied=true/Succeeded=false/PublicationPending=false and clear duplicate associations before deletion. Forced normal portal tick, then verified new retirement audit matching cleanup nonce on all4 before any external delete. Added holds and deleted ONLY IDs1–4 after exact correlation-marker checks; authenticated GET404 and all3 repository issue-list counts0 confirmed. Internal retired report/audit metadata deliberately retained (not queued), preventing stale publication retries or loss of controlled cleanup provenance. No unknown incoming reports were removed. Configured Ithaca access works through remote_python hostithaca as existing user UID1002 with sudo-n; no SSH/identity/agent configuration changed. Enabled only BugReporting.Forgejo.AllowAutomaticPublication=true in0600 runtime JSON in place, preserving all other values. Restarted only verified portal container, waited for container and local ingress health/public200. Recovery code can close ONLY portal-port5051 sockets in ingress namespace if stale edge pooling recurs; no shared proxy/game-service restart performed. Verified6 game containers retain identical StartedAt/restart counts. Reporting/Forgejo/publication flags independently re-read true. Ran live tick and read-only preview204; all3 trackers still0issues after publication activation, so no phantom pilots republished. Chose exactly one scheduler: explicitly set worker Actions variable REPORTING_WORKER_ENABLED=false, enabled/started existing prk-reporting.timer (OnCalendar03:00UTC, Persistenttrue). systemd is-enabled=enabled, is-active=active. Ran exact prk-reporting.service once as launch smoke against empty intake: Result=success, ExecMainStatus=0. Next actual timer fire2026-10-19T03:00:00Z; natural scheduled execution has not yet occurred and should be monitored. No model batch/report was created in smoke. Private local operational launch booleans synchronized; no credential values printed. Remaining follow-ups: first natural timer outcome, expired-token refresh observation, clean formal main validation run (previous was canceled), and remaining local branch/artifact cleanup after configured Git agent approval. Do not mark all historical checklist items/task done merely because launch toggles are active. Deployed mainc647 still has failed engine/client check statuses and a failed automatic deploy alongside successful manual portal4974; later cleanup audit resolved why statuses were red: corresponding validation run4973/API5090 is cancelled with started=UnixEpoch, so jobs never executed. No demonstrated engine/client code failure from that run. A clean validation run is still needed before calling overall release CI green. Checklist6 remains pending rollout/calibration rather than claiming completion from fixtures. This verifies actual signed-in Spiritech submission, scan/delivery and authoritative beta product flowing into worker job; direct fresh-profile ordinary/wrong-client denial is still not independently tested on production. Separate read-only execution in deployed analyzer confirms productContext('spiritech').likelyImplementationRoots=['PRK.Client/']. User's stale-session404 observation is not a substitute for complete production audience-isolation acceptance. Remaining overall launch validation includes ordinary/wrong-client/revoked-role isolation, controlled publication/withdrawal, expired-token refresh and successful chosen scheduler execution. Follow-up requested 2026-10-19: exempt fresh authorized Spiritech testers and bug_hunter users from daily reporting quotas; preserve per-report/file safety limits. Improve known-issue provenance and fidelity, including original-report links and attachment access. Read-only inspection of overnight Forgejo results confirms curated bodies contain only rewritten summaries (BugExecutor), no original link or evidence. Example: intake #8 has a clean pet screenshot, General curated #1 mentions that screenshot but provides neither attachment nor source link. Intake #9 has two clean screenshots likewise absent from General curated #2. Both originals are titled [spiritech] but their immutable payload product is general, so executor routed them to General; investigate submission/audience behavior separately rather than infer model cross-audience routing. Approved implementation scope: trusted Spiritech tester/bug_hunter daily-quota exemptions; Ctrl+V screenshot uploads through existing attachment pipeline with cursor-position body references; validated attachments (no manual approval) visible on published audience-authorized portal issues; source-faithful sanitized known issues with private source backlinks; controlled multi-select topic taxonomy and portal filters; audited General-to-Spiritech recategorization with fresh destination context, no automatic visibility widening; deterministic known-issue closure/reopening propagation to linked intake reports without overriding independent staff closures. Preserve immutable original text/evidence and private staff notes. Resumed after the emergency at user request. Both repositories are on feature/improve-bug-triage-routing. Saved checkpoints remain engines42380897b and worker4a7f17b. With explicit /open-pr authorization, committed the four follow-up files as engines211e86d41 (fix: Preserve staff changes during resolution retries). Both repositories are clean and pushed with upstream origin/feature/improve-bug-triage-routing; worker head4a7f17b. Emergency fix branch fix/canonical-item-mission-packets/a36d82da8 was left intact. No deployment or live issue modification. Open linked PRs: - Engines #2736 — https://git.project-rk.com/prk/engines/pulls/2736 — feature/improve-bug-triage-routing into develop, head211e86d41. Latest origin/developdf42e865e merge-tree check is clean; validation ran on the feature branch rather than a merged latest-develop tree. - Worker #1 — https://git.project-rk.com/prk/player-reporting-worker/pulls/1 — feature/improve-bug-triage-routing into main, head4a7f17b. User reports both PRs merged and portal deployment finished. Worker origin/main4e69bca includes merged PR1. Read-only authenticated, all-zero-report v3 preview from the Git host now succeeds (portal_ready=True); it returned400 while the portal rollout was pending. No report claimed or analyzed during these probes. Release/live-correction checklist remains open. Worker automatic deployment follow-up (user explicitly selected CI visibility, not a polling timer): implemented locally on build/auto-deploy-reporting-worker from origin/main4e69bca. With explicit PR authorization, committed the seven intended files as06dbec4 (ci: Deploy the reporting worker after main tests pass), pushed build/auto-deploy-reporting-worker with upstream, and opened worker PR2 — https://git.project-rk.com/prk/player-reporting-worker/pulls/2 — into main. Working tree is clean. Files: .forgejo/workflows/test.yml, Dockerfile, README.md, package.json, deploy/deploy-worker.py, deploy/restricted-command.sh and test/deploy_worker_test.py. PR2 is merged and the first automatic deployment is verified. Host checkout is clean at aa06b0adad164c072abf70fd9d2e5f0774e5e832. Deployment receipt records that exact revision, analyzer image sha256:cd62fb5556fadcb3ed87093f5c486985829ea6fbb9389175d7e05624eea65f70 and controller image sha256:90eeec228e2e2bf37b953225c82d5c3545cc23f9b59d3e1252cf8d389203b6f0. Running analyzer and both stable image tags match receipt; analyzer is running, health passes, restart count0, StartedAt2026-10-19T09:37:06.881165369Z. Live targeted portal-v3 readiness passes. CI latest push run5150 reports success and links https://git.project-rk.com/prk/player-reporting-worker/actions/runs/16 . Tea metadata omits SHA/job details and its jobs endpoint returns404, so no job-log content is claimed; successful run status plus independent receipt/runtime checks establish the rollout outcome. Daily timer remains enabled/active with next03:00UTC2026-10-20, and no model batch or report reprocessing was invoked by verification. Auto-deploy checklist is now verified; controlled v3 refresh is now in progress at the user's explicit request to delete published copies and rerun triage. Refresh reference reporting-refresh-20261019T094737Z. Privately exported exactly7 old publications (General1–2, Spiritech1–5),10 original intake reports5–14 and their9 native evidence records. Local artifacts: ~/.local/share/prk-reporting-ops/retriage-20261019T094737Z. Scoped DB export on Ithaca: /home/mathias/.local/share/prk-reporting-ops/retriage-20261019T094737Z/database-before.json, SHA256031b50cedbed323b176b09e8ffde51e9cbeff26f53c08141a3c1ef725694480f, preserving10 reports/8 decisions/9 uploads/7 snapshots. Shared reporting lock held by one-hour guardian on git-prk-server, PID2188654, root artifacts /root/.local/share/prk-reporting-ops/retriage-20261019T094737Z. Create release-lock there when processing finishes; daily timer/CI configuration unchanged. Allowlisted operator retriage commands on intake5–14 were processed through supported staff flow; old decisions archived/invalidated, all10 verified pending without leases. A transaction guarded to those exact IDs reset only obsolete canonical references/attempt markers and assigned fresh routing generations, so deleted publications cannot trigger attempted-create reconciliation. Original product/text/files unchanged. Deleted exactly7 ownership/hash-checked curated copies through issue API; both curated trackers verified empty. No intake/evidence deletion. Controlled real v3 refresh ran intake5–7 successfully, creating Spiritech known6–8 with structured reproduction, source links and topic tags (UI/Zoning/Chat). Intake8 correctly requested General-to-Spiritech correction, then its Spiritech analysis failed; controller stopped without automatic retry. Only generic analysis-failed/Error logging survived, so root cause is not yet established. Intake9–14 remain queued; all10 original bodies and9 native evidence records match the baseline. At user request, pause rerun and fix redundant known-issue comments/raw attachment references plus the analysis failure; additional request is inline video playback with controls/seeking on portal known issues. Temporary refresh guardian release requested after verifying refresh process ended; daily timer unchanged. No new batch started. Local clean follow-up branches: engines fix/clean-known-issue-publications from saved211e86d41 checkpoint and worker fix/diagnose-triage-analysis-failures from saved06dbec4 checkpoint. User explicitly authorized retry after returning to approve SSH. Both fetches succeeded. Clean follow-up branches were reconciled without published-history changes: engines fix/clean-known-issue-publications now based on origin/develope38196c65; worker fix/diagnose-triage-analysis-failures on origin/mainaa06b0a. With explicit PR authorization, committed/pushed the fixes and opened linked PRs. Engines16173901c on fix/clean-known-issue-publications into develop: #2738 — https://git.project-rk.com/prk/engines/pulls/2738 . Worker109bff0 on fix/diagnose-triage-analysis-failures into main: #3 — https://git.project-rk.com/prk/player-reporting-worker/pulls/3 . Both working trees are clean with matching upstreams. User reports portal follow-up deployed. Worker PR3 is verified merged at2026-10-19T10:57:45Z; latest worker push CI5161 is running (not yet claimed successful). Initial host check still showed previous aa06b0a receipt/runtime, healthy and matching both stable tags, so no selected reports resumed. BLOCKER: remote_python to ithaca failed with connection_error: SSH to10.144.92.85:22 returned No route to host. No remote retry, alternate credentials/transport, SSH configuration change or bypass attempted. User explicitly requested retry; Ithaca connectivity is restored. New portal container is engines-portal-ithaca-09b901bb8bf63f391e38a5ef0eca859106b0dcfc. Worker CI5161 is now success; host receipt/clean checkout are3c7db3311e35619c53f444c157a5ed5a7da4df16 (merged worker PR3), both stable tags and running analyzer match receipt, analyzer health and targeted portal-v3 readiness pass. Scoped SQL read verifies intake8–14 have no active leases and no successful new decision. Intake8 is already classifiedSpiritech with2 prior attempts and an expired normal lease;9 remains originalGeneral pending. Controlled resume of intake8–14 is complete and verified, without resetting attempts or deleting/redoing completed5–7. Resume artifacts: /root/.local/share/prk-reporting-ops/retriage-20261019T094737Z/resume-20261019T110424Z. All7 model analyses completed with accepted known proposals;9 also performed exactly one General-to-Spiritech recategorization followed by a successful destination pass.8 succeeded on its existing third permitted attempt. No technical analysis failure or repeated-recategorization regression occurred. Final outcomes across original intake5–14:9 issues published in Spiritech (known6–14), General tracker empty, and intake10 intentionally retained in private needs-staff-review because its assessment marks a possible repeatable item-creation/economy exploit sensitive. This is a safety hold, not a failed model run; no override/automatic publication was attempted. Latest private assessment37596 distinguishes screenshot observations from unproven persistence/duplication and gives developer next checks. Mapping: intake5→known6 zoning,6→7 chat configuration,7→8 console window,8→9 pet position (Pets/Movement),9→10 chat item links (Chat/Inventory/Input),11→11 Esc windows,12→12 flying,13→13 GMI,14→14 loot range. Verified scoped DB results: all10 original immutable fields (including original Product0 for8/9) unchanged; all9 complete evidence rows unchanged;8 evidence files attached to the9 published issues and1 evidence file remains with sensitive intake10. All decisions are applied with no analysis/publication pending;9 succeeded/published with fresh confirmations and correct audience,1 private reviewed state. All report/decision leases cleared. Scoped after-export is /home/mathias/.local/share/prk-reporting-ops/retriage-20261019T094737Z/database-after.json on Ithaca. Final Forgejo reads verify all10 original body hashes and9 native asset records unchanged, current General0/Spiritech9, each known issue has source/repro sections, correct tags, no raw body attachment IDs and exactly one untouched bot publication comment. Local final-api-verification.json preserves summaries. Both actual zoning video originals were downloaded through authenticated Forgejo access, original checksums matched, and ffprobe confirmed H264 with supported MP4 signatures. Positive production browser playback/authentication was not independently exercised; local real Chrome playback tests remain the browser evidence. The temporary resume guardian lock was released and nonblocking reacquisition verified. Worker remains healthy at3c7db33 with matching deployment receipt. No manual deployment or game-service restart was performed. Daily timer unchanged, next natural run2026-10-20T03:00:00Z. Remaining overall gates: observe natural scheduled run and handle sensitive intake10 through staff/security investigation; broader historical role/isolation acceptance items remain as previously recorded. Do not mark the whole launch task complete from this refresh alone. PRs retain local/browser/model replay evidence and limitations. Portal release must remain portal-only; worker main merge will use existing automatic CI deployment. Presentation/video follow-up implemented and verified locally: create canonical bodies with source and real native UUID attachment links (no raw opaque reference tokens), emit only one compact collapsed portal metadata comment per revision and fail closed if native evidence is missing. Legacy manifest parsing/immutable comments and existing staff-edited body protection remain. Portal embeds MP4/M4V and WebM via shared image/video renderer, controls/playsinline/metadata preload/no autoplay, signature+extension checks and authorized GET/HEAD/byte ranges with same-origin/nosniff/sandbox. Unsupported formats/codecs retain original downloads; no transcoding. Tests reproduced duplicate readable comments and missing video before fixing. All94 scoped bug tests pass including real disposable SQL, zero skips. Real local Chrome decoded rendered MP4/WebM frames, played/paused/sought both, verified206 ranges/HEAD/original-byte downloads, unsupported MOV fallback, mobile width and ordinary-user404. Source feature review covered10 changed files with no actionable findings; separate worker and manual cleanup remain outside that automated review scope. Existing live known issues Spiritech6–8 were safely tidied under exact author/body/updated-time and comment-ownership checks: source/native links moved into body, only duplicate prk-portal-details comments removed, immutable portal publication comments untouched. Before/after records saved in the refresh artifact directory. Re-read verified exactly one metadata comment and no raw body attachment IDs on all3. All10 intake body hashes and9 native asset records still match baseline. Actual routing failure reproduced in an isolated temporary analyzer container, not guessed: after General-to-Spiritech correction, saved report8 input had effective productSpiritech while original body saidGeneral; prompt still advertised productCorrection=true and model requested recategorization again. Strict validator rejected it with Automatic recategorization may only restrict General to Spiritech. This controlled diagnostic used one fresh normal lease (no proposal submission); its private prepared input is /root/.local/share/prk-reporting-ops/retriage-20261019T094737Z/diagnostic-pass/input.json. Diagnostic leaves normal lease expiry, no forced reset. Fix disables correction capability for already-Spiritech jobs and explicitly separates authoritative effective routing from historical submitted product. A second isolated real-model replay reused that saved input (NO claim or submission) with the corrected prompt and passed unchanged strict validation/source-read checks, yielding known with Pets/Movement tags. Result is private result-fixed-prompt.json, not published. Production analyzer was not replaced; temporary containers auto-removed and shared reporting lock released at completion. Worker also now retains safe allowlisted failureCode/known field diagnostics across analyzer/controller boundaries (schema, routing, source references, provider/runtime, budgets/deadline) without logging raw responses, provider messages, report content or tokens.29 Node/TypeScript +12 Python tests pass, production analyzer Docker build passes all41. No unsafe visibility widening, retry loop or invalid-proposal publication introduced. Next: verify/merge the linked PRs, portal-only release plus CI worker release, then resume only remaining intake8–14 with explicit recategorization follow-up for9 and verify final outputs. Reports5–7 already republished/tidied; do not delete or rerun those blindly. Natural scheduled-run validation remains pending. Forgejo test workflow gains a main-only deploy job dependent on successful tests and manual main dispatch; it reuses existing reporting SSH/host-key secrets. Host helper enforces clean main checkout, exact current origin/main SHA, shared triage/auth flock, read-only portal-v3 probe before build and activation, revision-tagged analyzer/controller builds, analyzer-only replacement, health/image verification, stable-tag advancement and atomic receipt. Superseded jobs skip activation. Failed activation restores prior tags/runtime; rollback failure is explicit. No model batch, source-snapshot refresh, credential rotation, game/proxy/portal restart or schedule change. Host bootstrap installed and verified through remote_python on git-prk-server: root-owned /usr/local/libexec/prk-reporting-deploy.py (SHA2565260abbca566116aa35ed5a683b8de730c4fcc9fc321e1ddbb585f76eb37e1c1), /usr/local/sbin/prk-reporting-command and0700 /var/lib/prk-reporting-deploy. Replaced ONLY the existing reporting-run key forced-command path; key material/restrict options and separate auth/user agent keys are unchanged. This intentionally grants that existing CI key bounded current-main deployment in addition to triage modes, not a shell/arbitrary ref. Private authorized_keys recovery backup is /root/.local/share/prk-reporting-ops/ci-deploy-bootstrap-20261019T093010Z. Unsupported/compound commands and invalid deployment SHA are denied. Analyzer image/start/restart count remained identical, daily prk-reporting.timer stays active, deployment checkout remains clean at0107a98. No live worker deployment has been run: it must run visibly through CI after committing/merging this workflow, per user preference. Validation:24 Node/TypeScript tests plus12 Python deployment tests pass; sh syntax and git diff checks pass. Production analyzer image build passes all36 tests. Added router test initially exposed missing build-stage router COPY; fixed Dockerfile and final image build passed. Tests cover main-only/dependent CI guard, invalid SHA/dirty/non-main refusal, both portal gates, stale revisions, shared lock exclusion, failed builds preserving images, health/receipt failures restoring runtime/tags, failed rollback escalation, idempotency, targeted nonredirecting readiness probe and restricted-command rejection. Actual Docker container creation by sha256 image ID also verified rollback reference compatibility. End-to-end CI SSH/deployment and receipt validation remain pending workflow commit/merge; no new commit permission inferred from setup request. The disposable fictional preview and dedicated prk-bug-triage-sql containers are stopped; /tmp/prk-bug-preview preserves fixture source, native Chrome Playwright acceptance and screenshot. Shared trade SQL stopped during initial resumed validation, so a separate disposable SQL instance was used rather than restarting shared infrastructure. No game service was restarted. Implemented locally: trusted fresh client-role quota exemptions; clipboard screenshot upload/reference insertion and previews; authenticated checksum-verified published evidence with raster-only inline responses; v3 structured sanitized reproduction content, topic taxonomy/filter and staff source/evidence backlinks; original Product preserved with ClassifiedProduct/routing generations, narrowing-only automatic routing and explicit staff reverse routing; old canonical/snapshot withdrawal and dependent reanalysis; deterministic linked-intake resolution cycles with conservative reopening ownership. Additive migration008 is NOT deployed. Portal must deploy before v3 worker (old portal rejects v3). Validation completed before pause: 147 focused portal tests passed with real disposable MSSQL, zero skips; 9 JS UI regressions and 24 worker tests passed. Native real Chrome Ctrl+V image clipboard, cursor preservation, CSRF binary upload, upload blocking/preview, ordinary text paste, publication fixture rendering/download/encoding, topic filtering, mobile layout and direct beta-evidence audience isolation passed via /tmp/prk-bug-preview/browser.mjs. Temporary fixture publication explicitly simulated validation; no real ClamAV/model/deployed integration run. Browser tool's earlier separate run was partial due missing JS capabilities; direct Playwright Chrome supplied the missing native clipboard evidence. Two static review rounds found material issues. First-round fixes verified in the 147-test run: immediate old-snapshot withdrawal independent of cleared report association, canonical-dependent reanalysis, routing-generation reversal, raw structured secret screening, compatible UTF8 request bounds and preserving staff reopening of bot-closed intake. Resumed validation complete: all155 focused portal tests pass with disposable real SQL and zero skips;9 JS tests and24 worker tests pass. Production analyzer Docker target builds and runs its24 tests. Latest rebuilt native Chrome acceptance passes clipboard PNG Ctrl+V, actual CSRF binary upload, caret/surrounding text, blocking/preview, normal text paste, sanitized publication sections/inline evidence/download, tag filters, encoding, mobile layout and direct beta-file denial for ordinary users. Fixture publication simulates scanner/model outcomes; real ClamAV/model/deployed v3 integration is not claimed. Additional failure tests verify failed PATCH retries versus lost acknowledgements and failed routing withdrawal. Follow-up review found pending-note retries could adopt later staff changes and confirmed bot ownership could be lost across a missed reopening cycle. Three new regressions failed against the checkpoint; fixed by saving source timestamps before network work, same-cycle suppression for an independent closure during the note, and carrying unchanged confirmed ownership across cycles. All pass. Review then found a weak tracked-context retry test: retries now clear EF tracking. Mutation verification removed the pre-network save and the strengthened regression failed as expected; save restored and all155 tests passed again. Final review was static and scoped to the follow-up; no review was rerun after the test-only strengthening. Separate worker source remains outside automated engines review coverage; its contract tests and production image build pass. Intentional policy: user explicitly authorized publishing validated original files without attachment approval. A review suggestion for an approval allowlist was not adopted because it conflicts with that policy. New UI/docs explicitly warn that antivirus does not remove credentials/personal information and originals are audience-visible, including files not referenced by the model. No automatic secret redaction or disclosure-approval guarantee is claimed. Implementation validation items are checked; task and release checklist remain open. Next: obtain authorization for additional commit/PR/promotion as needed, release portal/migration008 before v3 worker using a portal-only deployment, then controlled live report correction and scheduled-run validation. Forgejo lacks state-edit CAS; a staff action racing the final PATCH remains a documented limitation, use a hold while taking over. Remaining production validation includes Spiritech/wrong-client/role isolation, controlled publication/withdrawal and scheduled execution, plus automatic OAuth refresh when expiry requires it. General report/evidence/manual model triage and persistent auth after analyzer recreation are now verified. Source snapshot now tracks portal/main8983c62f4; running game engines intentionally remain cff8ba87c. Preserve deployed-component revision distinction; do not claim a unified new game release. Deployment safety: no remote/server mutation or deployment invoked during conflict work. Verified .github/workflows/deploy-ithaca.yml automatically runs on main push with scope auto; deploy-engines.sh may select full engine deployment and falls back to all when deployed versions cannot be determined. Therefore do not merge promotion PR2708 merely because conflicts are fixed: enforce an explicit portal-only release or guard automatic production deployment first to honor user's no-main-game-server-restart constraint. Do not push develop/main or merge either PR without addressing deployment effects. The worker code repository is populated and private; the three issue trackers remain fresh with no local test data transferred. PR2705 is open for engines; no production deployment. Revalidation on the final rebased branch passed94 real-SQL focused portal tests, five UI regressions and23 offline deployment tests. Worker eight tests and workflow lint pass. Remote worker test CI succeeded in26s; engine PR's engine/client checks are running (pending), not claimed successful yet. Legacy trackers and old beta automation remain untouched. Keep task in_progress until these outstanding operational acceptance criteria are met; do not imply local Compose validates production credentials or signature updates. Legacy import API follow-up: PR #2741 https://git.project-rk.com/prk/engines/pulls/2741 (feature/import-legacy-bug-reports → develop). Adds a small authenticated, source-idempotent text import endpoint through normal delivery/triage; no schema change or source-tracker mutation. Validation: 153 portal tests passed, 20 SQL-dependent skipped; SQL import concurrency not validated. The import API was subsequently deployed and verified. All 17 open Spiritech issues were imported as intake #22–#38; 41 closed issues were excluded by user decision. Descriptions, 13 comments and 16 attachment links were preserved; source issues unchanged. Repaired 11 escaped image embeds across 9 intake bodies without changing technical report data. Attachment binaries remain in the legacy tracker. Triage-label cleanup follow-up: PR #2744 https://git.project-rk.com/prk/engines/pulls/2744 (fix/reconcile-triage-workflow-labels → develop), commit be427a964. Isolated worktree: ~/Projects/worktrees/engines-triage-labels. Mutually exclusive primary states, durable command-label acknowledgement/retry and newer-command preservation. Validation after fast-forward to latest develop: 163 portal tests passed, 20 SQL-dependent skipped; diff check clean. Not deployed. Historical live stale labels still need state-aware reconciliation after rollout; Forgejo has no atomic comment/label precondition. Updated product requirement (supersedes earlier mandatory staff-review policy): never require staff review or an approved summary to advance valid reports through triage. Sensitive reports automatically become actionable private-only developer issues in the existing audience-specific private tracker (or safe duplicate links), link back to intake, and complete intake triage; they must remain excluded from player-portal publication. Sensitivity is a visibility restriction, not a workflow approval gate. Uncertain/incomplete classifications use an automatic conservative private handoff with explicit unknowns/needs-information rather than awaiting staff. Human intervention remains optional; preserve explicit staff holds, audience isolation, ownership/source validation and other security boundaries. Technical failures remain visible operational failures with bounded recovery, not invented successful decisions or mandatory review tasks. Implementation is prepared in paired PRs, not yet deployed: - Engines PR #2751 https://git.project-rk.com/prk/engines/pulls/2751 — commit84f80a7e5, fix/automate-private-sensitive-triage → develop; worktree ~/Projects/worktrees/engines-private-triage. Includes automatic sticky private handoffs, migration009 recovery without another model run, private/unpublished issue+duplicate lifecycle, comment-only staff retriage and v4 verified instruction projection. - Worker PR #4 https://git.project-rk.com/prk/player-reporting-worker/pulls/4 — commit1b49d8e, fix/automate-private-sensitive-triage → main; worktree ~/Projects/worktrees/player-reporting-worker-private-triage. Includes v4-only trusted staff direction with tracking/separation precedence, ordinary-comment isolation, instruction-ID diagnostics and v4 rollout gate. Final validation against current engines develop054a73dba: 207 portal tests passed with disposable MSSQL, 3 separate game-DB tests skipped; 33 worker Node tests and 12 deployment tests passed; changed JS syntax/diffs clean. Both worktrees clean and pushed. Full-stack/browser and real-model instruction obedience were not tested against these patches. User explicitly defers deployment until tomorrow because the new deployment path is blocked; no merge or deployment was performed. Once unblocked, deploy portal/migration009/v4 first, then worker. Production still uses the old sensitive-review policy until rollout; verify saved decision recovery, private closure/duplicate propagation and a fresh staff-directed retriage afterward. Existing processed staff comments must not be silently replayed. Planned extension — connect the in-game .bug command to portal reporting (planning only; no implementation started): replace Bytebin/paste-link and legacy Forgejo/GitHub issue-form instructions with one clickable portal form link carrying automatically associated diagnostics. Reuse AOEmu.PlayfieldEngine/Commands/BugCommand.cs capture scope: capture time, character identity/level/breed/side/profession, server/playfield/coordinates, active nanos, active/completed quests, equipment/armor/implants/inventory and full stat breakdown. Capture immutable live values at invocation, not later saved database state; do not retain session/player object graphs across network work. Prefill known environment/location facts but leave reproduction/expected/actual and unknown client/platform details to the player. Player previews included context and explicitly submits through the existing form/receipt, with no copy/paste or separate tracker account. Existing portal sign-in remains required and must preserve the handoff return path; this is not an auto-login feature. Implementation direction: a small authenticated engine-to-portal staging boundary issues an opaque, expiring link; snapshots/credentials/game cookies do not travel in URLs or logs. Bind access/claim to verified game-account ownership through existing portal account/server relationships; reject wrong-account, wrong-server, tampered and expired handoffs without disclosing diagnostics. Scope credentials to staging only, bound request size/rate/time and abandoned-data retention, make retries safe and retain context through form validation/login/reload. Final submission atomically associates immutable diagnostics and delivery intent using existing submission idempotency/quota/CSRF rules. Keep full diagnostics private for staff and authorized analysis through PRK.Reporting delivery/worker contracts; do not treat them as ordinary publishable uploads or copy raw inventory/stats/identity into the known-issue projection. Preserve existing General versus role-gated Spiritech selection; game server identity is not client-product proof or beta entitlement. Never truncate the snapshot into the 2000-character Environment field. Reuse existing Razor Submit/Receipt, BugSubmissionService, PortalAccountIdentity, GameAccountService ownership patterns, BugAccess, upload UX, additive schema migrations, private Forgejo intake/coordinator delivery, and HTTP/SQL reporting test fixtures. Extract one snapshot builder/contract rather than keeping old/new collectors; preserve the coordinator's no-game-assembly dependency boundary. No new authentication system, separate report form, generic workflow framework, client protocol change or triage redesign. Remove obsolete .bug text-store calls, full snapshot Console output and legacy issue links; remove shared registrations only if proven unused. Portal outage/disabled reporting yields an honest message and a plain portal reporting link when usable, never a false success or old pastebin fallback. Deployment/configuration must be coordinated across portal/coordinator and engines; planning does not authorize rollout/restarts. Acceptance: one in-game link reaches the existing authenticated form with complete invocation-time context, preview and no manual diagnostic copying; sign-in/validation/reload preserve it; explicit successful submission delivers exactly one report with staff/analysis-accessible private context; raw context never appears in player catalogue/published attachments; invalid/foreign/expired/replayed links and failures are handled safely; direct portal reporting and audience controls remain unchanged. Validate with command snapshot/escaping/bounds tests, portal HTTP auth/ownership/expiry/form tests, real-SQL atomicity/concurrency/retry tests and coordinator/privacy regression tests. During implementation, exercise signed-in and signed-out browser flows plus the actual in-game /start link. No tests or implementation performed during this planning extension. Refined .bug implementation scope (supersedes vague implementation choices above; implementation now authorized and started in the clean engines checkout on develop at 4aa3af58c; no commit or rollout authorized): 1. User experience: .bug remains argument-free. One in-game action labelled Continue bug report opens the existing portal form. Display captured character, server/location and UTC capture time with a collapsible full diagnostic preview; prefill only known environment facts. Reuse existing report-type/product selection, reproduction/expected/actual, screenshots and receipt. No auto-submit or second issue-tracker login. Include the existing session.SpiritechVersion when available, explicitly client-reported, and suggest Spiritech only if the signed-in portal user has the existing permission; retain user correction since a client session does not identify the faulty component. Unknown client version/platform stays unknown. 2. Snapshot: create one versioned immutable diagnostic payload from the live session before external I/O. Preserve the old capture categories and stat detail, with deterministic readable sections and explicit unavailable-section indicators rather than silent omission. No password/email/IP/auth cookie/token capture. Establish a bounded snapshot and fail visibly if exceeded rather than truncating. Capture must use appropriate game-state synchronization; do not assume CommandHandler is tick-thread-safe. Only detached values cross the asynchronous staging boundary. 3. Handoff storage/security: portal stages a private snapshot with server-scoped game account ID, character ID, capture time, request correlation ID and token digest. Use a narrow engine-only HTTPS staging credential mapped to a configured server, never a general worker/admin credential; caller-supplied server tags cannot change credential scope. Repeated identical staging request IDs resolve to the same staged record; changed payload conflicts. Link contains a cryptographically random short-lived token only, never the snapshot or game-session credentials. Proposed default validity is24h, configurable. Do not count staging as a submitted report. Bound staging per account/server and delete expired abandoned records via existing maintenance patterns. 4. Claim/resume: require existing portal login and preserve the local handoff return URL. Resolve the credential-selected server and current game account ownership using the existing portal account/server/email relationship (GameAccountService and server access rules), not a snapshot-supplied email. Existing email-claim trust is a dependency to verify, not an excuse to add token-only access or invent another account-linking flow. Only the matching signed-in owner may claim the draft; mismatch gets a safe switch-account/start-without-context option, never diagnostic disclosure. Ownership-checked claim binds to PortalAccountIdentity issuer/subject key and creates/reuses a stable submission ID; redirect to a clean account-bound draft URL. GET/link scanning must not irreversibly consume anything. Reload/back/login retries resume the same unsubmitted draft; report text need only survive the existing validation/login behavior, not a new autosave feature. Redact handoff paths/query tokens from application/proxy/access logs and suppress referrer leakage on the handoff page. 5. Submission and privacy: final POST reloads server-owned context by draft association; posted snapshot contents/IDs are not authority. Commit report, snapshot association, uploads, delivery intent and draft completion in the existing submission transaction. Same-ID retries return the same receipt; a draft cannot attach to a second report and concurrent tabs cannot create duplicate reports. Quota/validation/temporary failures retain the draft. After success the link/draft resolves only to the authorized receipt, not a new report or raw pending-report view. Store diagnostics as explicit private report metadata, not an ordinary BugUpload or expanded Environment field. Extend shared reporting schema/delivery/intake presentation and triage access narrowly; coordinator remains free of game-assembly references. Authorized triage may use relevant diagnostic facts, but raw snapshot rendering/attachments must never be automatically copied into published known-issue content or catalogue projections. Verify private intake receives the full context; passing only a portal link that the worker cannot access is insufficient. Reuse intake-body analysis if it preserves complete bounded context; negotiate a worker contract change only if actually required by its existing input limits. 6. Failure/release scope: success message means draft staging succeeded, not bug submission. On staging/configuration failure explain that diagnostics were not attached and offer the normal portal form; never claim automatic context or revive pastebin/legacy tracker links. Never fabricate a report on capture failure. Expired drafts offer a clean report or rerun .bug to refresh diagnostics. Portal/coordinator/schema/config must be deployed before enabling engine links; no deployment, production restart or automatic recovery of pre-expiry data is authorized here. Existing direct portal reports remain unchanged. No browser auto-launch protocol change, client UI integration, general draft autosave, authentication redesign or triage redesign. Ordered validation gates: (1) live-value snapshot coverage/detachment, missing sections, client hint, malicious names and bounds; (2) HTTP staging auth/server scope, idempotency/conflicts, rate/expiry/cleanup and token-log safety; (3) signed-out return and correct/wrong-owner claim, non-consuming GET, resume and product-role isolation; (4) SQL atomic submit/rollback, concurrent claim/tabs, duplicate POST/lost acknowledgement and context retention; (5) private intake/worker full-context delivery, exclusion from publication/attachments, unchanged plain reports; (6) real-browser signed-in/out reporting with screenshot upload and actual in-game /start link on supported clients. Each gate must pass before its checklist result is checked. Implementation checkpoint: .bug handoff implemented, uncommitted, on feature/portal-bug-command-handoff in /home/mathias/Projects/engines (base4aa3af58c). No rollout or restart performed. One dependency-free PRK.Reporting.Contracts project shares the bounded snapshot/staging DTO without coupling the coordinator to game assemblies. Capture takes the existing player async lock, detaches values before network I/O, and uses HeaderData.GameAccountId (the generic session AccountId is not populated by zone login). Context link uses a URL fragment, not query/path: continuation JS removes it, retains it in tab-local storage across login, and claims by CSRF POST before redirecting to an owner-bound draft URL. Hash changes and invalid fragments are handled without resuming stale context or entering a submission loop. Ownership requires verified OIDC email, matching current server/account email and existing server visibility; the SQL ownership query does not load passwords. Existing logout supports local return to continuation for switching accounts. Implemented staging: server-scoped bearer secrets, 256KiB effective request limit, 32k-character diagnostics, 24h default configurable expiry, per-account/server quotas, idempotent request/token hashes, bounded engine timeout and one identical transport retry. Final submission atomically commits private GameContext, normal report/uploads/delivery intent and draft completion. Private intake receives complete diagnostics; analysis prepends them before its existing40k limit without a worker contract change. Published content/ordinary attachments never copy this metadata. Migration012, schema validation, Docker restore dependency, maintenance and operator/command documentation updated. Legacy issue links/paste-store calls/full snapshot Console output removed. Verified: final container build succeeds (SDK10 / ASP.NET8.0.30; existing unrelated warnings). Final reporting/command suite with disposable MSSQL2022:267 passed,3 separate game-database tests skipped,0 failed. Includes snapshot live-value detachment/lock/gear/quests/stats, complete command success/fallback, staging/auth/scope/size/expiry/quotas, owner/audience/CSRF/form validation, real-SQL account ownership and concurrent staging/claim/submission plus rollback/cleanup, migration integrity/legacy adoption and private delivery/analysis/publication isolation. Static review was partial only because generated Avalonia artifacts were included; those generated files were subsequently removed. Its sole body-limit concern was disproved on the actual ASP.NET8 runtime: fixed-length and chunked oversized requests return413; removing RequestSizeLimit metadata makes both regressions fail with204; metadata restored and final tests pass. No static-review approval claimed. Chrome acceptance: isolated tool verified synthetic signed-out/in login return, encoded preview, stable IDs/reload/product navigation/validation, receipts and wrong-owner denial. Supplemental Chrome155 Playwright run passed actual PNG upload201, contextual submission/receipt, empty/invalid-fragment recovery and HTTP network audit (token only in one CSRF POST body, not request URL/header/referrer), with zero JS exceptions. Browser evidence and replay harness/script are in ignored .dev-data/game-bug/, results /tmp/prk-game-bug-browser-results.json; screenshot context-form.png was inspected. Final SQL log /tmp/prk-game-bug-all-portal-final.log; size negative-control log /tmp/prk-game-bug-size-control.log. Browser authentication/ownership is synthetic; real account ownership is separately SQL-tested. Real Keycloak end-session/login continuity and clicking /start in stock/Spiritech game clients remain unverified, along with production configuration/rollout and live Forgejo delivery. Keep final handoff-acceptance checklist unchecked and task in_progress. No deployment or game-server restart authorized/performed. PR publication: user explicitly authorized committing and opening a PR via /open-pr. Committed exactly the41 session files as ca8735ca8e1fedc8fcfa6531981aa5f448c1cbc0 (feature: Connect in-game bug reports to the player portal), pushed with upstream origin/feature/portal-bug-command-handoff, and opened draft PR #2834 https://git.project-rk.com/prk/engines/pulls/2834 against the verified repository default develop at4aa3af58c. No unrelated commits or files included, no force-push or history rewrite. Complete2106-line staged patch inspected; private metadata scan, JS syntax and whitespace checks passed. Working tree clean; remote feature head matches local. Existing267-passed/3-skipped SQL suite and Chrome evidence retained; no new test run or remote CI success claimed for the commit/push-only operation. PR explicitly lists live Keycloak/game-client acceptance and coordinated rollout as outstanding. Task status and final acceptance checklist unchanged. Ithaca staging credential provisioned with explicit user authorization: generated one256-bit random secret on ithaca.project-rk.com and appended it to root-owned0600 /etc/prk/ithaca/engines.env as AOEMU_REPORTING_STAGE_TOKEN and /etc/prk/ithaca/portal.env as GameBugReporting__ServerTokens__ithaca. Verified the exact existing server tag is lowercase ithaca, no token was previously configured in either environment file or portal runtime JSON, both new values are identical64-character hex, and ownership/modes/unrelated file bytes are preserved. Secret was never printed, copied locally or stored in repository/tracking content. Used the configured SSH IdentityAgent and normal host-key verification; normal SSH was necessary because remote_python cannot select the deployment's root user without a local Ithaca alias. Acquired existing engines/portal/workflow deploy locks nonblocking before mutation. Root-only before-change backups: /etc/prk/ithaca/.config-backups/game-bug-20261023T225724Z-ecec29f8. Verified every running container ID, start time and restart count unchanged. No deployment, restart, database mutation or code change performed; env_file values activate on subsequent container recreation/deployment. Portal/coordinator/engine rollout and actual Keycloak/game-client acceptance remain outstanding; final acceptance checklist remains unchecked. Current requested continuation: rebase PR2834 onto latest develop and also prepare Ergo to send .bug reports to Ithaca's portal/private reporting pipeline. Ergo scope is private runtime configuration only: inspect its exact server tag and existing settings, provision a distinct Ergo staging secret on Ergo and the corresponding Ithaca portal server-token entry, and point Ergo at the shared portal origin. Do not deploy/restart services or reuse the Ithaca environment's staging credential. Rebase completed locally onto origin/develop aad7ef5d65e592f09343f9baf550989a6672f645. New head a42795b9eaac874c7c50fb02e18736cb871a4687; backup chore/backup-portal-bug-handoff-ca8735ca8 preserves original published commit. Resolved BugCommand conflict by preserving upstream68548c0f5's shared BugReportPing.Find(args) last-token parser and passing client-reported chat RTT into the private snapshot; preserved existing client version. Added four version/ping combinations and command-level last-token precedence tests. Resolved BugWorkflowTests conflict retaining both all upstream legacy-client routing regressions and private-diagnostic delivery test. Rebased reporting/command suite with disposable MSSQL2022:292 passed,3 unrelated game-database tests skipped,0 failures. JS syntax and diff whitespace pass. Working tree clean after removing generated Avalonia artifacts. No client protocol, published-history base commits or unrelated work changed. Resolved access blocker after user requested continuation: SSH-backed git ls-remote/push sequence had timed out after60s at Gitea access. Local remote-tracking feature ref remains ca8735ca8e1fedc8fcfa6531981aa5f448c1cbc0, and no git/SSH process from the operation remains. The interrupted attempt did not establish remote state. On user continuation, verified both remote heads and successfully pushed the validated rebase with an explicit lease. Per access policy, stopped without retrying or changing credentials/agent/config. User requested continuation after the access issue; the required remote-head verification and explicit force-with-lease push have now completed. Existing PR2834 now points to a42795b9e and its body records the rebased validation. Latest read-only PR view reports open/mergeable with no WIP title prefix; no explicit ready-state change or merge was performed in this continuation. Ergo configuration provisioning is verified below. Only the explicitly requested private runtime configuration was provisioned; no production deployment, restart or report submission was performed. Existing Ithaca token configuration remains as previously verified. Access is now restored. Verified remote develop still aad7ef5d6 and feature head still ca8735ca8, then successfully force-with-lease pushed a42795b9e and updated existing draftPR2834 with292-passed/3-skipped rebased validation and preserved upstream ping/version behavior. Ergo read-only inspection succeeded: /etc/prk/ergo/engines.env is root-owned0600, AOEMU_SERVER_TAG is exactly Ergo (capital E), no staging token or portal URL is configured, and the existing engines deployment lock is present. Ergo preparation COMPLETE AND VERIFIED: portal public lookup for tag Ergo returned404, so performed a narrow read-only game_servers metadata query using existing site/database container configuration. Canonical registered tag is lowercase ergo; server remains non-public with database configured. Existing Ergo engine AOEMU_SERVER_TAG=Ergo is a display/environment label and was intentionally preserved; the portal derives authoritative server scope from its own credential mapping. Existing server-access permissions and reporter-ownership checks remain unchanged. Verified HTTPS connectivity from Ergo to https://portal.project-rk.com/health/ready returns200/ready=true. Generated a distinct256-bit Ergo staging secret on Ithaca and added GameBugReporting__ServerTokens__ergo to /etc/prk/ithaca/portal.env, preserving the existing ithaca credential. Added the matching AOEMU_REPORTING_STAGE_TOKEN and explicit AOEMU_REPORTING_PORTAL_URL=https://portal.project-rk.com/ to /etc/prk/ergo/engines.env. Verified the secret matches across hosts, differs from Ithaca's credential, both files remain root-owned0600, all unrelated bytes/settings are preserved, and every running container ID/start time/restart count remains unchanged. Held existing per-scope deploy locks during changes. Secret crossed only captured encrypted SSH streams/in-memory orchestration; never printed to the terminal, written locally or stored in repo/tracking content. Normal SSH root connections were required because remote_python cannot select root without a local alias; configured IdentityAgent and host-key verification were retained. Root-only before-change backups: Ithaca /etc/prk/ithaca/.config-backups/game-bug-ergo-20261024T100414Z-d819e80e and Ergo /etc/prk/ergo/.config-backups/game-bug-ergo-20261024T100415Z-1752034e. Values activate on subsequent container recreation/deployment. Ergo uses the existing shared portal/coordinator and trackers; no tracker write credential is installed on Ergo. No service restart, deployment, report submission, database mutation or repository change was needed for provisioning. Live staging/login/report delivery remains unverified until the new components are deployed; existing Ergo portal access restrictions still apply. Disposable rebase validation containers/network and local SQL-secret env files have been removed after successful continuation. Source and validation logs remain; working tree is clean and local/remote feature heads both equal a42795b9e. Final handoff-acceptance checklist stays unchecked; task remains in_progress for the outstanding live acceptance, not for rebase or credential provisioning. Ergo .bug deployment-failure investigation: user authorized an isolated worktree because the main checkout has unrelated uncommitted Team/Pets/NCU work. Created /home/mathias/Projects/worktrees/engines-ergo-bug-handoff on fix/ergo-bug-report-handoff at current origin/develop d97370577; no source edits/commits, original client work untouched. Read-only production inspection confirmed both Ergo PFEs run d973705779e0e4c34f5da54e342c791fc8d2800b with the correct portal origin and staging token matching the private host file. Ithaca's running portal is still portal_v0.1.7 at03aa879efc55e93449bdab16fc0009bf581ff3dd, started2026-10-24T00:13:36Z: it predates PR2834, lacks the staging endpoint and has no Ergo staging token in its runtime environment. An authenticated empty-JSON probe from Ergo to /api/game-bug-context returned404; no valid snapshot/report or durable data was submitted. Source comparison confirms GameBugApi/endpoint registration/migration012 are absent from that deployed portal revision. User then confirmed the portal deployment had not finished. Root cause established as component rollout mismatch, not a proven snapshot/code defect. No service restart, configuration mutation, application deployment or production DB mutation during investigation. Deploy portal/migration012 first, then the matching reporting workflow/coordinator so private context is delivered/analyzed; Ergo engines are already current and need no additional deployment for this mismatch. Separate analyzer worker needs no upgrade. Await completion and a real .bug retest; no extra code fix is currently warranted.
Checklist
21 of 29 complete- Create fresh private intake/general-curated/Spiritech-curated/worker repositories and restricted credentials. Configure portal-client spiritech_beta role and trusted client-scoped claim policy; verify infrastructure and unattended ChatGPT setup. Leave legacy trackers unchanged; no migration at launch.
- Deliver immutable authenticated reports, durable private upload staging/quarantine and native Forgejo evidence; ZIP-wrap unsupported types preserving bytes. Verify quotas, streaming, scanning, checksum/asset reconciliation and safe recovery from ambiguous issue/file delivery.
- Deliver shared General and spiritech_beta-role-gated Spiritech submission/catalogue flows with server-owned audience routing and My reports. Verify isolation across crafted POSTs, wrong-client roles, direct IDs, search/counts, caches, files, duplicate links and role revocation.
- Deliver one ChatGPT-through-Pi read-only analysis pipeline and restricted non-destructive executor for General and Spiritech; enforce product/audience destinations and no automatic beta-to-general exposure. Staff review stays in Forgejo. Verify injection boundaries, idempotency and human-edit protection.
- Build fresh worker repository with daily/manual pinned Pi workflow, reusing inspected patterns without changing existing triage-runner/beta automation. Provision image/secrets/auth; verify locking/audit/failure handling, manual dry-run and timer execution for both product paths.
- Validate portal/worker, SQL crash/race handling, Forgejo edge cases and hostile-file/output boundaries. Exercise real General and portal-client spiritech_beta-role login flows, wrong-client role rejection, revocation and cross-audience isolation. Launch fresh repositories; no legacy migration, rehearsals, restore exercises or DB rollback strategy.
- Rework triage for scarce staff: prioritize same-audience duplicate detection across fresh intake/curated history, check recent develop fixes and open PRs, and produce actionable developer handoffs without requiring root-cause proof. Separate publication pause from review; validate that only genuine safety/ambiguity exceptions require staff, with preserved evidence and human overrides.
- Published audience-specific README.md to main in all three reporting trackers with user authorization: player-bug-intake fe014bd, player-known-issues 78a8138, spiritech-known-issues dc43ff0. Verified staff commands, labels, proposal schema, bounded comment context and publication behavior against implementation; formatting/example JSON checks pass. Remote main hashes match local commits and all three checkouts are clean.
- Allow triage to correct a misfiled General report to Spiritech with durable routing audit and fresh destination-scoped duplicate/code context. Preserve original submissions/evidence, prevent automatic visibility widening, and verify retries plus existing-publication handling before live correction.
- Implement and locally verify fresh tester daily-quota exemptions, native clipboard screenshot insertion through the existing upload pipeline, and audience-authorized validated evidence rendering/downloads without an approval workflow.
- Implement and locally verify structured known-issue reproduction content, topic tags/filtering, private source/evidence backlinks and deterministic linked-intake closure/reopening with staff overrides and ambiguous-reply safeguards.
- Release migration008 and portal v3 before worker v3 without restarting game engines; audit and reprocess affected overnight reports, verify production publication/evidence/audience/lifecycle behavior and the next scheduled run. Preserve original reports and files.
- Configure and verify visible Forgejo CI deployment after successful worker-main tests: existing restricted SSH transport, main-revision validation, shared triage lock, clean fast-forward source, revision-tagged images, portal-v3 readiness gate, analyzer-only activation/rollback and unchanged daily triage scheduler. No deployment polling timer.
- Remove duplicate readable known-issue comments, render owned attachment references as clickable links in the tracker body, retain one compact immutable portal metadata comment per revision, and safely tidy the three already-published entries without touching originals.
- Embed supported MP4/M4V/WebM evidence on portal known issues with controls, seeking/authorized byte ranges and HEAD, no autoplay, signature checks and original download fallback; verify real browser playback and audience isolation.
- Reproduce and fix repeated recategorization after General-to-Spiritech correction, distinguish current routing from historical submission metadata, and add credential-safe stage/contract failure diagnostics. Verify saved-input real-model replay before resuming publication.
- Implemented POST /api/bug-worker/import with existing bearer authentication, source-derived identity/audience, stable retries and changed-content conflicts, validated text/source backlinks, no schema changes, and normal delivery/worker claiming. Portal tests via SDK8 CI image: 153 passed, 20 SQL-dependent skipped; diff check clean. API documented in PRK.PlayerPortal/README.md. Not deployed; local bulk import and attachment binaries remain follow-up work; old trackers untouched.
- Completed the user-approved import of all 17 open Spiritech issues; excluded all 41 closed issues. Intake #22–#38 are unique, Spiritech-routed and were verified triage:ready. Verified every delivered report field against stable local payloads; pilot retries returned 200 with identical IDs and no duplicate creation. Preserved descriptions, 13 attributed comments and 16 absolute attachment links without truncation; rephrased one private workflow reference. Source states/update timestamps unchanged. Private snapshots, receipts and mapping: ~/.local/state/prk/legacy-imports/spiritech-open-20261019T144636Z. Subsequently repaired 11 escaped image embeds in 9 intake bodies (#22,26,28,29,31,35,36,37,38); verified actual Forgejo Markdown rendering and unchanged technical JSON/title/state/labels/assignees/comments. Before/after backups in image-repair/. No application changes, forced triage or publication; attachment binaries remain in legacy tracker.
- Code fix committed as be427a964, PR #2744 https://git.project-rk.com/prk/engines/pulls/2744, branch fix/reconcile-triage-workflow-labels in isolated ~/Projects/worktrees/engines-triage-labels. Central mutually exclusive primary states; durable staff-command acknowledgement/retry with newer-command protection; controls and descriptive/current work-context tags preserved. Latest-develop validation: 163 portal tests passed, 20 SQL-dependent skipped; diff clean. Production code deployment remains unverified. User-authorized manual cleanup completed: removed exactly ready/requested (20 labels) from intake #5–#14 after read-only SQL confirmed terminal idle decisions and comment histories proved all request IDs acknowledged, none newer. Preserved nine complete states and #10 needs-staff-review, plus fix-in-development tags. Verified issue text/state/comments/assets unchanged and all ten database report/decision records exactly unchanged, including revisions/leases/processed IDs; no rerun. Pending imports #22–#38 left ready/untouched. Private before/after snapshots and receipts: ~/.local/state/prk/label-cleanup/20261019. Forgejo atomic label/comment race limitation remains documented. Unrelated deployment checkout untouched.
- Production reporting analyzer switched to openai-codex/gpt-5.6-terra. Verified exact model exists in deployed runtime catalogue and dedicated provider auth is configured. Persisted TRIAGE_MODEL in /etc/prk-reporting-worker.env, under shared nonblocking reporting lock with no controller running; recreated only analyzer using the same pinned image SHA e4ae0f028c75a51c95b6bf35b71e7dffb445bb223fe8e8d6561f446014f7c645. Runtime environment matches target and /health succeeds. Medium reasoning/budgets, scheduler, code snapshot, portal and game engines unchanged. No triage started or provider inference performed; actual model-account access remains to be exercised in the first approved run.
- Started production GPT-5.6 Terra triage for exactly imported intake #22–#38 (17 fixed report IDs), in batches of 8/8/1 under the shared reporting lock. Transient service prk-spiritech-terra-20261019.service on git-prk-server; durable status/logs at /var/lib/prk-reporting-runs/spiritech-20261019-terra. First report (intake #22, db9b135a-6132-1954-5be1-916c5d25e686) produced a known proposal accepted by portal, confirming real provider access; batch 1 remains running. No automatic retries on controller failure; no unrelated claims or old-report retriage. Refreshed checksummed filtered code snapshot from clean latest develop f60c1d59aa4fc24ca83a55f91aaabd6e0bccc342, manifest tree 3677f47e5d569c747a950a2d9e48b8036a07e5d1af374823c41e17cd00378c6e, 5149 files, before starting; analyzer image/model unchanged and health verified. Previous snapshot retained as code.previous-spiritech-terra. Local archive/selection/provenance: ~/.local/state/prk/triage-runs/spiritech-20261019-terra. Await remaining analyses and verify final decisions/labels/publications; do not mark complete on proposal acceptance alone.
- Implementation complete in isolated engines worktree ~/Projects/worktrees/engines-private-triage and worker worktree ~/Projects/worktrees/player-reporting-worker-private-triage, both branch fix/automate-private-sensitive-triage; not committed/deployed. Sensitive/uncertain/unsafe-publication-text reports automatically create actionable private-only developer issues (or safe duplicate links), with sticky report/cache privacy flags, no public manifests, catalogue/evidence/My reports denial, and no staff approval gate. Ordinary handoffs get developer issues even with publication paused. Changed source content/targets queue automatic analysis; actual safety/ownership/hold/technical failures remain blocked, not fabricated successes. Quarantined evidence stays withheld while a private handoff proceeds. Internal lifecycle snapshots close/reopen linked originals and both canonical/intake duplicates for private and unpublished issues; tests preserve manual overrides, holds and lost-ack ownership. Additive migration 009 backfills privacy, withdraws affected caches and resumes saved known/uncertain review decisions like #10 without re-running the model or unrelated completed reports; real-SQL migration/idempotency tests pass. Worker prompt/helper/docs and local full-stack scenarios aligned; JSON contract unchanged. Validation: 198 portal tests passed including SQL, 3 separate game-database tests skipped; worker 30 Node tests + 12 deployment tests passed; changed JS syntax and both diffs clean. Full-stack browser scenario updated/syntax-checked but not run. Rollout remains outstanding: deploy portal/migration009 first, then worker prompt update; verify #10/private lifecycle in production before completing operational acceptance. Unrelated deployment checkout untouched.
- Completed live staff retriage training for intake #36 using Oatbag's own comment #38062 ('not duplicate, want to track separately'); no operator comment, forced reset or manual classification. Authorized user105 in live StaffUserIds, portal same image healthy; Oatbag/user added the currently required tag, which portal consumed and queued ready. Public edge404 was repaired by the other deployment agent; verified public root200 and authenticated targeted preview200 with correct Spiritech report and Oatbag clarification included. Ran production gpt-5.6-terra controller only for report0ad05ad7-9251-4fed-8a8f-ae66a6a827fb under shared reporting lock. Exactly one proposal accepted/applied; fresh audit #38071 and duplicate backlink #38073, final triage:duplicate to prk/spiritech-known-issues#23. Model still judged perk-preview action information covered by #23 despite its broader timer scope; retriage requests analysis rather than forcing the requested classification. No unrelated reports processed; pending new code not deployed. Host receipt/logs /var/lib/prk-reporting-runs/retriage-36-comment38062; private local before/after comments/issue at ~/.local/state/prk/retriage-36-comment38062.
- Implemented in pending private-triage worktrees: authorized retriage marker comment alone queues once, with optional legacy requested labels consumed after durable handling. Staff allowlist, ownership, holds/hidden controls, active leases and processed-comment idempotency preserved; optional corrected proposals still retain their separate approved signal. LF/CRLF and marker-only comments supported consistently. Added seven regression cases for comment-only operation, unauthorized authors, deferred holds/leases and repeated polling. Removed redundant local helper label creation; docs updated. Validation: 205 portal tests passed including real SQL, 3 game-DB tests skipped; 30 Node + 12 deployment tests passed, JS syntax/diffs clean. Not committed/deployed; live staff test still uses the prior tag-required version.
- Implemented in existing pending engines/worker private-triage worktrees, not committed/deployed. Explicitly negotiated v4 jobs separate staffInstructions[{commentId,authorId,text}] from ordinary staffNotes: only actual current intake-comment authors on StaffUserIds, excluding bot, are promoted; imported attribution and role claims remain untrusted. Latest ten verified comments are independently bounded/sorted, preserving v1–v3 wire shapes and mixed legacy notes as untrusted. Worker requires v4, fails on downgraded jobs, preserves redaction, exposes instructions separately in model prompt and gives explicit staff separation direction precedence over default deduplication, while privacy/audience/tool constraints remain non-overridable. Prompt requires acknowledging applicable comment IDs/effect; analyzer prompt-attempt and accepted-proposal diagnostics record included IDs without raw text (input inclusion, not proof of comprehension). Deployment readiness now negotiates v4 before building/activation; existing proposal JSON unchanged and no new migration beyond009. Tests cover verified vs forged/bot/historical discussion, current allowlist/revocation, bounds, legacy compatibility, downgrade rejection, instruction forwarding/redaction and v4 features. Validation: 207 portal tests passed including SQL, 3 game-DB tests skipped; 33 Node+12 deployment tests passed; JS syntax/diffs clean. Full-stack/real-model obedience test not run. Deploy portal/v4/migration009 before worker; no live rerun or service changes performed.
- Deliver one detached invocation-time diagnostic snapshot preserving existing .bug coverage, UTC capture/server metadata and existing client-reported version. Stage through server-scoped engine authentication with bounded storage, correlation-id retries and expiring hashed tokens. Verify synchronized capture, completeness/missing sections, limits, auth/server isolation, retry conflicts, cleanup and no sensitive logging.
- Deliver ownership-checked handoff into the existing portal Submit form: preserved login return, non-consuming GET, issuer/subject-bound resumable draft and clean URL, stable submission ID, context preview/environment prefill and permission-gated product suggestion. Verify current game-account/server/email ownership trust, wrong-owner recovery, expiry, reload, validation, role isolation and token/referrer-log protection.
- Atomically complete the draft and associate server-owned immutable private diagnostics with normal report/uploads/delivery intent. Verify SQL rollback/concurrent tabs/lost acknowledgements, quota/validation draft retention and same-receipt retries. Deliver full context into private intake/authorized analysis, never ordinary publishable uploads/catalogue projections; preserve no-game-assembly coordinator boundary and unchanged direct reporting.
- Replace .bug paste-store/legacy links and snapshot Console output with one Continue bug report link, clear staging-versus-submission wording and honest no-context portal fallback. Document coordinated portal/coordinator/schema-before-engine configuration. Verify signed-in/out real-browser completion with screenshot upload plus actual in-game /start on supported clients, full privacy/security regressions and unchanged direct reports. No rollout/restarts without separate authorization.
- Area
- Project Rubi-Ka
- Project
- engines
- Kind
- Feature
- Task ID
tsk_4cwztt3jmn- Updated