The latest 11.77 report still shows the undefined-index error fixed locally in 2c5cdd78a. Exercise service-account binding followed by user search with unset and configured filters, and prove failed binding cannot proceed to search. The separately reported oplog observer error is not established as the authentication cause.
Thanks to Nissulya and xet7 !
Fixes#6692,
Pass activity values as sprintf options and discard Spacebars helper metadata so card and sidebar feeds show actual titles and labels instead of literal percent placeholders. Preserve the security-aware viewer and sanitizing. Verify substitution using the real i18next formatter and register browser assertions for both feeds.
Bound attachment requests and defer long rate-limit cooldowns while preserving rate-limit state. Recover missing public links from the closest historical capture, retain provenance, and skip optional failures so remaining content synchronization continues.
Synchronize Git to all active destinations before collecting source content. Reuse the local archive for concurrent destination processes, show combined per-mirror issue and release counters, and retain separate mirror-named logs. Stop content writes after archive failure and preserve restart checkpoints.
An unset LDAP_USER_SEARCH_FILTER was indexed after service-account binding, causing the reported undefined index TypeError instead of searching users. Preserve configured filters and reject invalid types explicitly.
Thanks to Nissulya and xet7 !
Fixes#6692,
Describe removing the card field value rather than deleting its definition. Retain 25 correct rule and activity values, preserve percent placeholders and add positive/negative regression checks.
Thanks to xet7 !
Emit only In short, Security, translation language names, thanks and the exact changelog anchor. Keep other details in the changelog and verify security retention, omitted developer entries and version-specific links offline.
Thanks to xet7 !
Keep detailed translation entries in the changelog and audit, but list only affected languages in release notes. Require explicit language metadata, preserve other topic details, and anchor release heading extraction. Verify nested detail removal and missing-metadata failure offline.
Thanks to xet7 !
Retain 30 correct values preserving attachment scope, storage names, account states and visibility settings. Resolve card-show-lists context against the settings row and toggle.
Thanks to xet7 !
Replace Portuguese date wording and preserve both setting and changing dates. Retain 39 correct automation and HTML-placement values; leave attachment participle agreement open after inspecting assembled controls. Add positive and negative date-trigger regression checks.
Thanks to xet7 !
Retain twenty-five correct translations, preserving admin constraints, mapping fallback, notification scope and public versus private access.
Thanks to xet7 !
Use consistent overtime-work terminology for manually classified recorded hours, preserving the hours unit and separating this flag from due-date expiry.
Thanks to xet7 !
Preserve canonical query examples and explain literal special-character escaping. Add positive example and negative malformed-wording coverage.
Thanks to xet7 !
Retain nineteen correct restoration and data-integrity labels, preserving field identifiers, board scope and administrator-only permission. Leave Complete state terminology under review.
Thanks to xet7 !
Retain twenty-nine correct administration values, preserving failed versus paused states and success versus failure outcomes. Leave context-dependent Complete under review.
Thanks to xet7 !
Distinguish the time window for failed attempts from an unsuccessful window. Retain twenty-nine correct support, accessibility and account-state labels.
Thanks to xet7 !
Retain thirty correct storage, upload, authentication and custom-translation strings, preserving byte units and irreversible deletion warnings.
Thanks to xet7 !
Apply the instance visibility policy at the shared before-insert hook so copies, imports and lazy helpers cannot create public boards. Keep policy enforcement independent of security logger availability.
Thanks to xet7 !
Use the correct native ReVo komplet entry and retain six checklist state translations plus thirty correct authentication, custom metadata and date labels.
Thanks to xet7 !
Record dated repair commit, corrected example coverage and current counts. Preserve open language and browser validation requirements.
Thanks to xet7 !
Replace misconfiguration wording with value removal, retain fifty-two valid rule and hierarchy labels, and preserve translated comma-separated example names in review coverage.
Thanks to xet7 !
Update dated audit counts, evidence and upcoming changelog with the verified local repair commit. Keep remaining language and browser review open.
Thanks to xet7 !
Use a singular member reference and a finite past verb with the established swimlane term. Retain fourteen correct rule and filter translations after semantic review.
Thanks to xet7 !
Update dated local review and exact counts in short audit, evidence and upcoming changelog, preserving remaining validation requirements.
Thanks to xet7 !
Update dated local hash and exact reconstructed counts in short audit and upcoming changelog; remaining language/browser validation stays open.
Thanks to xet7 !
Express stopping observation/subscription rather than looking. Retain 37 correct restored shortcut, upload, invitation and SMTP values; keep overtime terminology unresolved. Verify placeholders and both translation ledgers.
Thanks to xet7 !
Update dated local review and exact reconstructed counts in short audit, evidence and upcoming changelog. Keep unresolved terminology and browser validation open.
Thanks to xet7 !
Update dated local repair hash, exact reconstructed counts and remaining validation scope in short audit, evidence and upcoming changelog.
Thanks to xet7 !
Replace foreign JJJJ/TT abbreviations with canonical YYYY/DD notation in three format labels. Retain 37 correct restored field, email and export values. Verify correction records, placeholders, key order and unchanged acceptances.
Thanks to xet7 !
Keep dated short audit and changelog current with actual local review, reconstructed counts and remaining language/browser validation.
Thanks to xet7 !
Retain 49 directly reviewed correct values. Preserve assigned-card scope, comment/read restrictions, field types and none/unknown states. Keep the lime color term and earlier uncertain findings open.
Thanks to xet7 !
Update dated short audit, actual local source hash and exact progress. Correct the complex-versus-complete dictionary attribution and keep completion terminology unresolved.
Thanks to xet7 !
Use observation terminology for watch settings. Retain 33 correct restored values, including transparent subtask compounds after checking ReVo task vocabulary, and attachment/template/mode controls. Completion wording remains under review.
Thanks to xet7 !
Update dated local review progress and exact counts. Record directly fetched ReVo task source without claiming full completion terminology validation.
Thanks to xet7 !
Update dated short audit, evidence and upcoming changelog with actual local review and reconstructed counts. Remaining language and browser validation stays open.
Thanks to xet7 !
Keep dated short audit and changelog current with actual local commit and verified counts. Record failed completion reference retrieval as unresolved, preserving the broader review scope.
Thanks to xet7 !
Name the Enter key explicitly in string-template item guidance. Retain 52 correct restored search, report, organization and storage values, preserving logical operators, commands and placeholders. Completion and subtask terminology remain under review.
Thanks to xet7 !
Retain 53 directly reviewed correct rule, card-view and search values. Preserve action polarity, wildcard and comma-separation instructions, operator syntax, HTML tags and placeholders. Uncertain terminology remains in the restored queue.
Thanks to xet7 !
Record the dated Esperanto settings review and exact progress. Shorten Audit.md while preserving accumulated notes in Audit-Evidence.md and keeping all pending, provenance and browser validation requirements open. Verify audit and changelog checks.
Thanks to xet7 !
Name the Enter key explicitly instead of using the direction inwards. Retain 64 correct restored import, export, invitation and deletion values; preserve vendor menu labels, JSON property names and placeholders. Verify correction and unchanged-value ledgers.
Thanks to xet7 !
Update dated local audit, evidence and upcoming changelog with repair commit and reconstructed progress. Wider translation validation remains open.
Thanks to xet7 !
Use ongoing observation rather than merely looking at boards. Retain 59 correct restored board/card controls and warnings after direct review. Verify correction ledger, placeholders and unchanged values.
Thanks to xet7 !
LDAP errors were serialized as empty objects because their name and message are non-enumerable. Preserve diagnostic name, message, code and reason through the existing secret sanitizer. Verify certificate and credential diagnostics plus disabled logging.
Thanks to Nissulya and xet7 !
Refs #6692
Update dated local audit evidence and upcoming changelog with reconstructed counts, review commits and four remaining context-dependent Danish labels.
Thanks to xet7 !
Retain 68 correct values after direct review. Preserve technical endpoint examples, region identifiers and migration outcome distinctions. Obsolete migration labels remain in translation scope without claiming the corresponding feature is active.
Thanks to xet7 !
Retain 63 correct translations after direct review, including shared Danish and English Start, Stop and Support vocabulary. Preserve byte units, ISO week numbering and scheduled-job outcome distinctions. Keep ambiguous free and Complete labels awaiting context validation.
Thanks to xet7 !
Update the short audit, evidence and upcoming changelog with actual local repair commit and reconstructed counts. Translation repairs and broader validation remain open.
Thanks to xet7 !
Review restored Danish values directly, retaining 41 correct translations. Correct singular adjective agreement and preserve the malloc allocation method in the heap diagnostic. Verify correction records and unchanged acceptances.
Thanks to xet7 !
Use the shared log-directory reservation for organization reports and update remaining path examples. Verify report paths with offline organization fixtures.
Thanks to xet7 !
Remove unvalidated deposit and null board IDs from source-card scope. Publish deposit content beneath its own reactive visibility-filtered board cursor, applying destination assignment restrictions and reactive card children. Filter status counts by visible assigned scopes.
Require destination write access before pointer changes and subtask landing structures, and deny client pointer rename bypasses. Summarize blocked writes in Problems. Positive decisions, scope/dispatcher inventory and existing subtask/status suites pass; browser regression syntax-check passes with live execution pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Require source write access for authoritative and DDP link creation, including pointer changes. Treat explicit non-writing source roles as a ceiling on delegated writes, covering legacy self-created links. Match UI permissions and remove the link action from the non-writer menu. Record denied writes in bounded Problems summaries.
Actual shared permission decisions for every role, creation/deny inventory and existing link and role suites pass. Browser regression syntax-check passes; live execution pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Domain-approved inviters must hold an allowed inviter role on each requested board. Site admins retain access to real boards; missing boards fail closed. Validate the complete grant before creating or changing any invitation code or sending mail, and summarize rejected grants in Problems.
Role and grant inventory plus invitation email suites pass. Browser regression syntax-check passes; live execution pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Use operation/YYYY-MM-DD_HH-MM-SS for Unix and Windows build logs, mirror launcher and data reports, translation push reports, conformance and speed diagnostics. Preserve earlier same-second runs with reserved suffixes. Keep record timestamps in their existing data format.
Path and collision fixtures, build progress and parity, mirror launcher and Transifex suites pass. Shell syntax checks pass; Windows execution was not available. Update the internal release preflight inventory used by parity checks.
Thanks to xet7 !
The saved 2026-09-14 run abandoned its accepted English upload after a status GET returned 502, preventing all 241 target uploads. Add bounded safe-read retries, throttling delays respecting Retry-After, and visible upload/job/retry progress. Do not resubmit uncertain failed writes.
Offline tests reproduce source-job recovery without duplicate submissions, throttle timing, permanent error behavior, retry bounds and Retry-After parsing. Existing upload, locale retry and pull suites pass; no remote uploads were run.
Thanks to xet7 !
Resolve code-scanning alert 540 by removing a regex sanitizer stub. Test malformed script end tags with the existing sanitize-html parser. The reported location is test-only, not an application sanitizer.
Thanks to GitHub CodeQL and xet7 !
Reject invitation field writes, array mutations, parent replacement and rename destinations. Inspect actual modifier paths so top-level profile field reporting does not block ordinary preference updates. Record denied invitation changes through bounded Problems summaries.
Profile guard and existing invitation suites pass. Browser regression syntax-check passes; live execution pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Check write capability and authoritative card board before button dispatch and again in the shared action dispatcher. Board buttons without a card remain supported. Record denied contexts in bounded Problems summaries.
Role and boundary decisions plus dispatcher inventory and existing rule suites pass. Browser regression syntax-check passes; live execution pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Align board title, card settings and all rule mutations with existing DDP administrator policy. Preserve site-admin access and record refused management attempts in bounded Problems summaries.
Actual guard and endpoint inventory tests pass along with card-settings and rule suites. Browser regression syntax-check passes; live execution pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Reject foreign-card REST and DDP comment inserts and prevent DDP rebinding from bypassing the boundary. Keep card-authoritative legacy comment listing. Add bounded Problems summaries and attack, negative insert inventory and browser regression coverage.
Targeted Node suites pass; browser regression is syntax-checked with live execution pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Enforce the canonical role policy for both sides of list, swimlane and checklist moves, scoped imports, attachment renames and history writes. Record denied attempts through bounded Problems summaries without allowing logging failures to bypass authorization.
Add role-matrix decisions, the reported moveList attack, sibling guard inventory and a browser regression. Targeted Node suites pass; live browser execution remains pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Add critical upcoming release entry and dated remediation progress. Record passing policy, negative insert inventory and catalog coverage; live browser execution and nine other reports remain pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Apply instance visibility policy to direct board creation and card-to-board conversion. Record blocked public overrides with bounded Problems summaries, preserving enforcement if logging fails. Positive policy and negative insert-inventory suites pass; browser regression is syntax-checked but live execution remains pending.
Thanks to Wenhao Wu, Southeast University and xet7 !
Update dated progress with 349 reviewed Danish values and 3,709 restored values still awaiting validation. Keep translation repairs open while prioritizing the requested wekansec21 security findings.
Thanks to xet7 !
Review thirty complete values on 2026-09-14. Preserve OR versus AND operators, executable examples, title/comment/label matching, pagination and date predicates. Retain correct Danish unchanged; ambiguous export wording remains open.
Thanks to xet7 !
Review thirty complete values on 2026-09-14. Preserve zero/one/multiple result counts, not-found subjects, creator/assignee and created/modified distinctions, time periods and predicates. Ambiguous export wording remains unreviewed.
Thanks to xet7 !
Update dated audit and current summaries with 230 reviewed Danish values, 407 retained original findings and 3,828 restored values awaiting validation. Keep pending and uncertain review scope intact.
Thanks to xet7 !
Review thirty full values on 2026-09-14. Preserve background continuation and slower-completion warning, batch range, attachment counters, temporary lockout cause and later retry. Retain valid Danish orange unchanged.
Thanks to xet7 !
Update dated audit and changelog totals to 200 reviewed Danish values, 377 retained original findings and 3,858 restored values awaiting validation. Preserve all pending repair scope.
Thanks to xet7 !
Synchronize dated audit and changelog with 170 reviewed Danish values, 347 retained original findings and 3,888 restored values awaiting validation. All pending and uncertain language work remains open.
Thanks to xet7 !
Update dated summaries with two repaired diagnostics and twenty-eight retained values. Record 15,538 corrected findings, 287 retained and 3,948 restored values awaiting validation. Remaining review is open.
Thanks to xet7 !
Update the dated audit and current summaries to eighty reviewed Danish values, 259 retained findings and 3,978 restored values awaiting review. Preserve pending repair scope and distinguish wording review from parser correctness.
Thanks to xet7 !
Record dated validation of fifty Danish values in total. Synchronize summaries to 229 retained findings and 4,008 restored values awaiting validation. Remaining repairs remain open.
Thanks to xet7 !
Update dated summaries after twenty correct Danish translations were retained. Record 199 reviewed original findings and 4,038 restored values awaiting validation; all remaining repairs and uncertain wording remain open.
Thanks to xet7 !
Review complete Danish meanings on 2026-09-14. Preserve correct wording, identifiers, count spacing and left/right directions. Record reviewed values without changing translations or claiming the remaining restored queue complete.
Thanks to xet7 !
Review all 4,058 restored values on 2026-09-14 and add token-inventory regression coverage. No mismatches found. Keep every restored value awaiting language validation; structural validity does not establish fluency.
Thanks to xet7 !
Update the dated audit and current changelog summaries with 18,131 correction records. All 308 pending original findings and wider fluent review remain open.
Thanks to xet7 !
Replace three additional Arabic/French labels on 2026-09-14, preserving noun-only versus Change actions. Reuse existing spent-time wording and native sorting terminology. Full participle and agreement remain low confidence pending fluent review.
Thanks to xet7 !
Record the dated source commit and 18,128 verified correction records. Keep all 308 pending original findings, restored values and uncertain date terminology under review.
Thanks to xet7 !
Replace the additional Arabic Change Due Date title on 2026-09-14. Reuse existing Due Date terminology and the native Change imperative used by neighboring date popups. Wider fluent terminology review remains open.
Thanks to xet7 !
Correct stale TODO Later and upcoming aggregate totals on 2026-09-14. Record 15,536 corrected original findings, 308 pending, and 18,127 correction records. Preserve historical batch snapshots and all unresolved fluency work.
Thanks to xet7 !
Update dated audit progress to 18,127 correction records and 308 pending original findings. Record native terminology sources and the verified display-only semantics; full grammar remains open.
Thanks to xet7 !
Replace French labels on 2026-09-14. Preserve the display-only meaning of no-parent, using native Hide rather than deleting the relationship. Parent compound and bound-state adaptation remain low confidence pending fluent review.
Thanks to xet7 !
Update the dated audit with 18,125 correction records and 309 pending original findings. Verify source HTML emphasis, removal of Arabic and future-state wording. Keep grammar review explicitly open.
Thanks to xet7 !
Replace Arabic visibility messages on 2026-09-14, preserving future state and HTML emphasis. Feminine agreement and full future construction remain low confidence pending fluent review. All correction records pass structural verification.
Thanks to xet7 !
Record the 2026-09-14 repair commit, 18,123 verified corrections and 310 pending original findings. Keep restored values and low-confidence grammar explicitly open.
Thanks to xet7 !
Replace the Arabic error with native-source-derived permission denial on 2026-09-14. Preserve the restriction to viewing this page. Combined grammar remains low confidence pending fluent review. Verify all 18,123 correction records and placeholder inventories.
Thanks to xet7 !
Review local accessibility and parent-card values on 2026-09-14. Record ten additional keys, including a Venda inheritance instruction in the Veps locale, without claiming a fluent replacement or reducing pending counts.
Thanks to xet7 !
Update the audit and upcoming changelog with the standalone escape-marker follow-up. Full Veps prose review remains pending; translation completion counts are unchanged.
Thanks to xet7 !
On 2026-09-14 compare all escape runs against English, preserving the open full language review. Record dictionary access and authority limits.
Thanks to xet7 !
Repoint four missing hashes to local commits with matching subjects. Report unresolved links without a contradictory success message, propagate checker failures and treat an unchanged changelog as a successful check.
Thanks to xet7 !
On 2026-09-14 document d0c247094, passing example checks and the still-open full language review without changing completed-language counts.
Thanks to xet7 !
On 2026-09-14 restore exact source comparison, escaping and Boolean examples. Positive and negative regression checks preserve the open Veps language queue; Finnish prose remains awaiting repair.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
On 2026-09-14 directly inspect locale JSON and native field keys; keep full language review open rather than treating syntax repair as translation completion.
Thanks to xet7 !
On 2026-09-14 isolate review of Finnish-seeded labels, distinguish native source evidence from full phrase validation and preserve all filter syntax requirements.
Thanks to xet7 !
On 2026-09-14 resolve emphatic-letter extraction substitutions while retaining complete diagnostic modifier review and source authority limits.
Thanks to xet7 !
On 2026-09-14 preserve only one board versus all cards in this list, including missing All in the Arabic label. Full commands remain low confidence pending native review.
Thanks to xet7 !
On 2026-09-14 preserve selecting all versus removing selection from all. Derived command and action noun remain low confidence pending native review.
Thanks to xet7 !
On 2026-09-14 inspect removed migration imports and surviving locale inventory. Preserve repair scope without implying an active feature; distinguish Integrity from Integration evidence.
Thanks to xet7 !
On 2026-09-14 use visually inspected engine and storage candidates, preserving MongoDB. Cross-variety compound and bound form remain low confidence pending native review.
Thanks to xet7 !
On 2026-09-14 verify Level and Zoom In/Out letters from rendered dictionary pages, retaining cross-variety adaptation and full input command review.
Thanks to xet7 !
On 2026-09-14 reuse directly attested native software labels and align notification terminology. Full muted warning remains under review.
Thanks to xet7 !
On 2026-09-14 preserve irreversible deletion and future loss of all lists, cards and actions associated with this board. Full warning and derived agreement remain low confidence pending native review.
Thanks to xet7 !
On 2026-09-14 replace Kter and Arabic board import labels with native import terminology. Action noun and full command remain low confidence pending native review; these are additional repairs outside the original queue.
Thanks to xet7 !
On 2026-09-14 inspected rendered bibliography and authentication/method entries. Correct 105 explanations from extracted MC£ to printed MCΓ, retaining unresolved Moroccan suitability and grammar review. Translation values and progress counts are unchanged.
Thanks to xet7 !
2026-09-14: Directly inspect dictionary text for Analysis and Structure. Preserve cross-variety source markers and unresolved legacy-font spellings; leave the complete label pending.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming to 15,529 corrected and 315 pending original findings, with 18,104 correction records. Preserve cross-variety provenance and full-language validation scope.
Thanks to xet7 !
2026-09-14: Replace four French labels, preserving method/type, default and display distinctions. Inspected Authentication candidate is cross-variety MC£; script rendering, bound form and full phrases remain low confidence.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,526 corrected and 318 pending findings, with 18,100 correction records. Preserve full-language validation scope.
Thanks to xet7 !
2026-09-14: Replace French help, retaining drag/drop reordering versus click-to-open behavior. Native Click/Change and existing dictionary terms support components; full instruction remains low confidence.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,525 corrected and 319 pending findings, with 18,099 records. Preserve source authority limits and full-language review scope.
Thanks to xet7 !
2026-09-14: Preserve two alternative input methods and the combined drag/drop action. Dictionary Drag and indexed Place support components; full software adaptation and clipboard borrowing remain low confidence.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,524 corrected and 320 pending findings, with 18,098 records. Preserve Kabyle provenance and open full-language validation scope.
Thanks to xet7 !
2026-09-14: Replace French and Arabic copy labels, preserving copied object and clipboard destination. Inspected Clipboard candidate is a Kabyle metaphor; borrowing and full command phrases remain low confidence.
Thanks to xet7 !
2026-09-14: Preserve uppercase/lowercase matching semantics; French typography excerpts and Tifinagh alphabet casing do not establish native software terminology. Leave the full instruction pending.
Thanks to xet7 !
2026-09-14: Record indexed Value paradigm correction and unchanged progress counts. Preserve full instruction and wider language validation scope.
Thanks to xet7 !
2026-09-14: Replace derived uzal with indexed IRCAM Value paradigm wazal. Preserve %{value}, substitution meaning and original French provenance. Direct PDF access failed; full instruction remains low confidence.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,522 corrected and 322 pending findings, with 18,096 records. Preserve cross-variety evidence and open language validation scope.
Thanks to xet7 !
2026-09-14: Replace French help, preserving both literal HTML space entities and OR. Inspected cross-variety Separator and Space Character candidates support components; full instruction remains low confidence.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,521 corrected and 323 pending findings, with 18,095 correction records. Preserve indexed evidence and full-language validation limits.
Thanks to xet7 !
2026-09-14: Replace French help with in-place-of-value paraphrase preserving %{value}. Native component usage and indexed Format support wording; bound forms and full software instruction remain low confidence.
Thanks to xet7 !
2026-09-14: Establish display-only No Parent scope from board schema. Avoid deriving singular parent terminology from lexical amawlan or substituting visual position for the actual relationship. Keep full wording review open.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,520 corrected and 324 pending findings, with 18,094 records. Retain exact cross-variety provenance and open validation scope.
Thanks to xet7 !
2026-09-14: Replace French label and preserve markdown format name. Reuse existing icon and workspace terms; inspected CNAM icon candidate is a starred cross-variety proposal, not normative Moroccan usage. Full wording remains low confidence.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,519 corrected and 325 pending findings, with 18,093 correction records. Preserve open language validation scope.
Thanks to xet7 !
2026-09-14: Replace French checkbox text, preserving confirmation action and workspace deletion scope. Native Verify and Deletion support components; full phrase and workspace adaptation remain low confidence.
Thanks to xet7 !
2026-09-14: Authoritative audit progress shows the three upload statuses were outside the original flagged queue. Preserve 15,518 corrected and 326 pending original findings, with 18,092 correction records.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,521 corrected findings and 323 pending. Preserve full-language validation and provenance scope.
Thanks to xet7 !
2026-09-14: Replace three French upload statuses and refine two earlier file restriction labels with directly attested Files plural. Preserve progress versus failure and upload versus avatar scope. Full status and permission adaptations remain low confidence.
Thanks to xet7 !
2026-09-14: Replace two Arabic labels while distinguishing upload and avatar file restrictions. Preserve colons. Native Type, File, Permission and Upload support components; plural and full permission constructions remain low confidence.
Thanks to xet7 !
2026-09-14: Use directly attested native Hide command, preserving ALL scope and original Arabic provenance. Checklist compound and full noun phrase still require language validation.
Thanks to xet7 !
2026-09-14: Update audit and Upcoming progress to 15,516 corrected findings and 328 pending. Reference the tested local repair; preserve broader validation and low-confidence grammar scope.
Thanks to xet7 !
2026-09-14: Replace Arabic wording, preserving checked-item scope rather than all checklist items. Native Hide and Check roots support components; derived passive plural and full grammar remain low confidence.
Thanks to xet7 !
2026-09-14: Distinguish the indexed Format noun from unverified full placeholder wording. Preserve literal placeholder and HTML space syntax; leave both repairs pending.
Thanks to xet7 !
2026-09-14: Repeat future deletion predicate for field history so it cannot attach to the from-all-cards phrase. Preserve original provenance and counts; full grammar remains low confidence.
Thanks to xet7 !
2026-09-14: Preserve no undo, removal from all cards and destruction of field history. Record native components and low-confidence full warning coordination.
Thanks to xet7 !
2026-09-14: Preserve failure time window in seconds, distinct from lockout duration/count threshold. Record native components and low-confidence time-window and error adaptations.
Thanks to xet7 !
2026-09-14: Preserve failures before lockout as count threshold. Record indexed native Before and error-to-failure adaptation with remaining low confidence.
Thanks to xet7 !
2026-09-14: Preserve lockout duration in seconds, distinct from failure window. Record native duration/block components and low-confidence bound noun and plural.
Thanks to xet7 !
2026-09-14: Preserve removal of card field value rather than board field definition, with exact placeholders. Record native components and low-confidence technical Value adaptation.
Thanks to xet7 !
2026-09-14: Preserve active field name to value assignment in card, exact placeholders and quotes. Record native component evidence and low-confidence technical Set adaptation.
Thanks to xet7 !
2026-09-14: Preserve active import object, destination and source with exact percent placeholders. Record native import noun and low-confidence derived actor and location grammar.
Thanks to xet7 !
2026-09-14: Preserve active removal of checkmark and exact percent placeholders, distinct from state or item deletion. Record native components and low-confidence mark nominalization and relations.
Thanks to xet7 !
2026-09-14: Preserve active checkbox checking, checklist/card relations and exact percent placeholders. Record native checkbox evidence and low-confidence actor and full grammar.
Thanks to xet7 !
2026-09-14: Preserve hierarchical subtasks and this-board destination. Record indexed native Place imperative and failed direct access; full software adaptation remains low confidence.
Thanks to xet7 !
2026-09-14: Distinguish regional Wait/Hope polysemy and failed direct PDF inspection. Preserve full pending migration progress scope and unchanged counts.
Thanks to xet7 !
2026-09-14: Verify Tasks counts list cards and preserve alternative move-out or higher-WIP remedies. Keep unresolved terminology pending without changing values or counts.
Thanks to xet7 !
2026-09-14: Verify zero means no limit in actual parser despite positive-integer English help. Preserve locale source meaning and reject font choice as regional terminology proof.
Thanks to xet7 !
2026-09-14: A failed PDF fetch cannot prove Integer or Positive entries absent. Preserve pending messages and direct subsequent research toward mathematical vocabulary.
Thanks to xet7 !
2026-09-14: Preserve positive integer and per-page scope while recording indexed Number evidence and cross-region source limits. Values and pending counts unchanged.
Thanks to xet7 !
2026-09-14: Remove masculine actor prefix from the passive relative modifying feminine Board. Preserve original correction provenance and counts; derived agreement remains low confidence.
Thanks to xet7 !
2026-09-14: Preserve future assignment of unmapped members to current user. Record native components and low-confidence fallback composition.
Thanks to xet7 !
2026-09-14: Distinguish association relative from Continue homograph and retain low confidence for derived mapping imperative. Correct Copy evidence key. Values and original counts unchanged; correction checks pass.
Thanks to xet7 !
2026-09-14: Preserve your imported board having some members and mapping selected members to your users. Record native components and low-confidence association and import grammar.
Thanks to xet7 !
2026-09-14: Independent normalized/indexed URL retrieval fails certificate-chain verification. Record that no PDF was inspected and preserve pending status; other repairs remain actionable.
Thanks to xet7 !
2026-09-14: Record indexed parallel IRCAM invitation and failed direct fetch. Preserve pending status because Welcome does not prove Invited and the exact native wording remains uninspected.
Thanks to xet7 !
2026-09-14: Replace unflagged Kabyle-seeded wording, preserving active completion and all five location placeholders. Record native completion evidence and remaining low-confidence grammar.
Thanks to xet7 !
2026-09-14: Preserve active undoing of checklist completion and exact percent placeholders. Native edit reversal supports Undo, while derived actor, completion noun and full checklist wording remain low confidence.
Thanks to xet7 !
2026-09-14: Preserve selection of your existing user to use as this member. Record native components and low-confidence existence and use-as composition.
Thanks to xet7 !
2026-09-14: Preserve all cards of this list removed from the board and return from Archive via matching menu labels. Record native components and low-confidence full coordination; archiving remains distinct from permanent deletion.
Thanks to xet7 !
2026-09-14: Align Menu and Export Board controls with repaired import instructions. Preserve your board, ordered navigation and copying text from the downloaded file. Record native component sources and low-confidence derived morphology and sequence.
Thanks to xet7 !
2026-09-14: Replace wrong-language label and confirmation. Preserve board-title placeholder and future removal of the current user from all cards on this board. Record native components and low-confidence membership adaptation and grammar.
Thanks to xet7 !
2026-09-14: Preserve every deleted content category, future inability to recover board contents and unconditional no-undo warning. Record native components and low-confidence grammatical composition.
Thanks to xet7 !
2026-09-14: Record local repair 7caee4baa, 350 pending findings and passing correction checks. Preserve language confidence limits and remaining restored/unflagged validation.
Thanks to xet7 !
2026-09-14: Replace French confirmation and align the related notification label. Preserve all notifications and unconditional inability to undo. Native component evidence is recorded; composed confirmation and action agreement remain low confidence. Update the older notification regression to match reviewed terminology.
Thanks to xet7 !
2026-09-14: Record fee3de6db, check/uncheck scopes and remaining language validation. Update audit to 15,493 corrected and 351 pending, including 216 Tamazight. All 18,060 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace three French values preserving Hide checked items, Check ALL items OF A LIST and active Uncheck ALL reversal. Native checkbox/hide/remove components support provisional wording; nominalization, passive and full grammar remain low confidence. All 18,060 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 371ccad6b, operation/scope distinctions and remaining language validation. All 18,057 correction checks and three metadata suites pass; original counts unchanged.
Thanks to xet7 !
2026-09-14: Record df6e03f46, scheduling/resume distinctions and remaining language validation. All 18,051 correction checks and three metadata suites pass; original counts unchanged.
Thanks to xet7 !
2026-09-14: Repair four unflagged labels preserving Scheduled plural versus Automatic singular and Resume versus Complete. Native Red Moon/Dialect components support provisional wording; migration adaptation and derived grammar remain low confidence. All 18,051 correction checks pass.
Thanks to xet7 !
2026-09-14: Record cda2d947b, restricted permission scope and remaining language validation. Update audit to 15,490 corrected and 354 pending, including 219 Tamazight. All 18,047 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French preserving ONLY move cards, SELF-assignment and comment permissions. Native components support provisional wording; self-assignment paraphrase and whole grammar remain low confidence. All 18,047 correction checks pass.
Thanks to xet7 !
2026-09-14: Record c002054d5, preserved notification scope and remaining language validation. Update audit to 15,489 corrected and 355 pending, including 220 Tamazight. All 18,046 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French while preserving future YOU notification for ANY change on THIS board. Native notification/each/sent-to-you components support provisional wording; feminine plural passive and full grammar remain low confidence. All 18,046 correction checks pass; fluent/browser validation remain open.
Thanks to xet7 !
2026-09-14: Record 5e5519f2f, exact native evidence and single-token tests. Keep pending date-boundary and uncertain mention wording open; additional IRCAM PDF could not be inspected. All 18,045 correction checks and three metadata suites pass; original counts unchanged.
Thanks to xet7 !
2026-09-14: Record 9daf257e4, preserved syntax and pending date boundary wording. Update audit to 15,488 corrected and 356 pending, including 221 Tamazight. All 18,044 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French preserving exact query parameter, cards IN swimlanes and specified title matching. Native Matching/Title/Given components support provisional wording; Swimlane-as-Path, specified adaptation and full grammar remain low confidence. Days-ago-or-less findings remain pending.
All 18,044 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 3f2d9c726, preserved search scopes and remaining language validation. Update audit to 15,487 corrected and 357 pending, including 222 Tamazight. All 18,043 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace three French values preserving default archive exclusion, ALL archived AND unarchived cards, predicate token, and title/description/custom-field scope on THIS board. Native components support provisional wording; passive/plural/full grammar remain low confidence. All 18,043 correction checks pass.
Thanks to xet7 !
2026-09-14: Record e0f16c497, metasyntax preservation and remaining language validation. Update audit to 15,484 corrected and 360 pending, including 225 Tamazight. All 18,040 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French prose while preserving exact query metasyntax and cards belonging to a board assigned TO organization/team. Native Given and local group terms support provisional wording; relative passive, assignment adaptation and whole grammar remain low confidence. All 18,040 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 129fa829e, syntax preservation and remaining language validation. Update audit to 15,482 corrected and 362 pending, including 227 Tamazight. All 18,038 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French while preserving operator tokens, colon, repeated username parameter and emphasis. Assignee-only versus member OR assignee scopes remain distinct. Reuse native Username and existing local role paraphrases; full grammar remains low confidence. All 18,038 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 1493cc244, preserved placeholders and indexed evidence limits. Update audit to 15,480 corrected and 364 pending, including 229 Tamazight. All 18,036 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French while preserving mentioned YOU, card/comment/list/swimlane/board and all five exact placeholders. Indexed IRCAM mention entry supports a provisional verb; PDF redirects to HTML and full wording remains low confidence. Native Mastodon person-directed activity supports object component only.
All 18,036 correction checks pass; fluent and browser validation remain open.
Thanks to xet7 !
2026-09-14: Record 381d18eb3, permission scopes and remaining low-confidence validation. Update audit to 15,479 corrected and 365 pending, including 230 Tamazight. All 18,035 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French administrator and Arabic normal-member descriptions and Activities label. Preserve card view/edit, member removal, board settings and activity view permissions, including normal-member inability to change settings. Native UI components support wording; full grammar and activity-log adaptation remain low confidence.
All 18,035 mechanical correction checks pass. Fluent and live browser validation remain open.
Thanks to xet7 !
2026-09-14: Record f903af89d and direct native Home evidence. Preserve unresolved full archive restoration wording and complete audit scope. All 18,032 correction checks and three metadata suites pass; original counts unchanged.
Thanks to xet7 !
2026-09-14: Replace Arabic with exact native Mastodon Home label, corroborated by MediaWiki Home-page wording. Full archive restoration instruction remains pending; standalone label evidence does not prove header/button wording. All 18,032 correction checks pass.
Thanks to xet7 !
2026-09-14: Record repair 7d1e0ef15, component evidence and low-confidence grammar. Update audit to 15,477 corrected and 367 pending, including 232 Tamazight. All 18,031 correction checks and three metadata suites pass.
Thanks to xet7 !
2026-09-14: Replace French while preserving checkbox click and board selection. Native MediaWiki supports checkbox and selection components; compound, plural and full instruction remain low confidence. All 18,031 correction checks pass.
Thanks to xet7 !
2026-09-14: Document repair 7dcaf17cf, native component evidence and remaining low-confidence language validation. Update original audit counts to 15,476 corrected and 368 pending, including 233 Tamazight.
All 18,030 correction checks and three audit/changelog suites pass. Restored values, unflagged strings and earlier uncertain wording remain in scope. No remote uploads performed.
Thanks to xet7 !
2026-09-14: Replace three French values while preserving failed migration scope, Retry versus Resume, successful retry notification and no failed migrations to retry.
Native Mastodon and non-fuzzy Dialect support components. Migration adaptation, derived plural/passive grammar and full wording remain low confidence. All 18,030 mechanical correction checks pass; fluent and live browser validation remain open.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for bc7b01940 with verified inventory and remaining native validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Preserve Delete versus Pause, this scheduled job confirmation and success versus failure in five unflagged values. Job adaptation and derived grammar remain low confidence.
Validation: 18,027 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 7a49eb16b with verified counts and remaining native validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 34a98e0d1 with verified counts and remaining native validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 10b082127 with verified inventory and remaining native validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Preserve Team settings, return/save actions and S3 success versus failure in five labels. Success uses completed Saved notification. Derived save noun, passive agreement and full phrases remain low confidence.
Validation: 18,011 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for c82cef74f, verified correction count and remaining native validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Preserve selected boards, star/unstar, all starred items and not-yet-anything meaning in six unflagged values. Passive and negative grammar, star adaptation and swimlane term remain low confidence.
Validation: 18,006 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for d6a73fae4, verified counts and remaining native validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Preserve star/unstar, board/page distinctions, top-of-your-boards-list location and count placeholder in nine labels. Star vocabulary reuse and full grammar remain low confidence.
Validation: 18,000 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 9af74b9d0, verified counts and explicit native validation limits. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Preserve new due time, When/Where labels, previous due value, four-line layout and exact placeholders. Actor past, deadline compound and full grammar remain low confidence.
Validation: 17,991 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 2557151f0, verified counts and remaining native validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 6c1388962 with verified counts, source semantics and explicit confidence limits. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Preserve container distinction and Copy Template to Many Cards versus Copy Checklist from Template. Six French/mixed values repaired. Container adaptation, checklist noun and full grammar remain low confidence.
Validation: 17,986 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 747e1d96e, distinguishing unflagged repairs from original counts and preserving validation limits. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Use directly attested Template component for seven labels, including Save as Template previously using Subject. Preserve Add/Create and card/list/board scopes. Plurals and full phrases remain low confidence.
Validation: 17,980 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 1f30de7d6 with verified counts and native validation limits. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 67e2d101b, verified counts and remaining language validation. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for 148e72446, including original versus unflagged repair counts and language validation limits. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Update upcoming changelog and audit evidence for a2a88d405 with verified counts and explicit language validation limits. Three metadata tests pass.
Thanks to xet7 !
2026-09-14: Preserve swimlane movement, all cards in this list and restore-all scope. Full phrases and swimlane terminology remain low confidence. Keep the existing generic Restore alternative.
Validation: 17,952 correction checks pass.
Thanks to xet7 !
2026-09-14: Record archive alternative and native control repairs in 14c2b82da, verified counts and remaining language validation. Changelog and audit regression tests pass.
Thanks to xet7 !
2026-09-14: Preserve the list archive alternative and activity retention; replace inherited Kabyle Save and Search controls with attested native labels. The assembled archive hint remains low confidence.
Validation: 17,948 correction checks pass, including placeholders, formatting and newer translation preference.
Thanks to xet7 !
2026-09-14: Record dce7f41cd, preserved placeholders and low-confidence clauses. Refresh audit and upcoming changelog; original counts unchanged. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace inherited Kabyle-leaning archive wording in four activities, preserving objects, nested locations, completed movement and exact placeholders. Latin script alone is not treated as an error. Passive forms, swimlane adaptation and whole clauses remain low confidence.
Validation: 17,945 correction checks pass, preserving translation preference.
Thanks to xet7 !
2026-09-14: Record 66c5df4fe, preserved intent/placeholders and low-confidence wording. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace three French/Arabic values. Preserve confirmation intent, this-board scope, question marks and exact %s placeholder. Native software supports the confirmation frame; derived verbs and full clauses remain low confidence.
Validation: 17,941 correction checks pass, including placeholders and translation preference.
Thanks to xet7 !
2026-09-14: Record cbc2bf400, preserved action/state scopes and low-confidence grammar. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace seven Arabic/French labels. Preserve Move to versus Restore from Archive, card scope and completed states. Native MediaWiki attests action verbs; full clauses and passive states remain low confidence for native review.
Validation: 17,938 correction checks pass; placeholders and translation preference preserved.
Thanks to xet7 !
2026-09-14: Record 38debcc33, preserved scopes and low-confidence grammar. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace seven Arabic/French values. Preserve board/list/card negative scopes, singular this-board moved status, and warning that the list containing this card is archived. Derived forms and full clauses remain low confidence for native review.
Validation: 17,931 correction checks pass, preserving placeholders and translation preference.
Thanks to xet7 !
2026-09-14: Record fbe388603 and distinguish inspected native logo evidence from French body text. Counts unchanged; full labels remain low confidence. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Inspect the native Archives du Maroc logo embedded on page 1 of a University Mohammed V press release. Add direct lexical provenance to nine archive records; French body text is not native evidence. Full kanban labels remain low confidence.
Validation: all 17,924 correction checks pass; no values or counts changed.
Thanks to xet7 !
2026-09-14: Record 5dca9f38d, indexed evidence limits and low-confidence full phrases. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace nine Arabic/French labels with Archive and Move-to-Archive wording, preserving all, board, card, list and selection scopes. Ministry indexed institutional archive terminology supports the noun; direct page access timed out. Full labels remain low confidence for native review.
Validation: 17,924 correction checks pass; placeholders and translation preference preserved.
Thanks to xet7 !
2026-09-14: Record 0488199cf, preserved original provenance and explicit recipient wording. Counts unchanged; grammar remains low confidence. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Refine two earlier filter labels with an explicit To whom recipient and feminine card passive, matching the assignee labels. Preserve No assignee and original French provenance. Relative grammar and responsibility paraphrase remain low confidence for native validation.
Validation: all 17,915 correction checks pass; counts unchanged.
Thanks to xet7 !
2026-09-14: Record 2e15e9f7b, preserved scopes and low-confidence grammar. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace five French labels. Preserve singular/plural, No assignee and all-cards versus current-card board scope. Responsibility paraphrases, relative clauses and derived forms remain low confidence for native review.
Validation: 17,915 correction checks pass; placeholders and translation preference preserved.
Thanks to xet7 !
2026-09-14: Record 13f8fbd14, preserved capability scopes and low-confidence wording. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace six French role labels and descriptions. Preserve assigned-only visibility and distinct normal editing, read cannot edit and comment-only capabilities. Derived forms, assignment paraphrase and complete clauses remain low confidence for native validation.
Validation: 17,910 correction checks pass, including placeholders and translation preference.
Thanks to xet7 !
2026-09-14: Record 5da9a2084, preserved scopes and low-confidence wording. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace seven Arabic/French labels. Preserve member versus assignee, negative scopes, other filters and active-filter edit instruction. Derived forms, responsibility paraphrase and full clauses remain low confidence for native validation.
Validation: 17,904 correction checks pass; placeholders and newer translation preference preserved.
Thanks to xet7 !
2026-09-14: Record 9f60960f4, preserved scopes, native Hour evidence and low-confidence full phrases. Refresh audit and upcoming changelog. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace five Arabic/French labels, preserving spent versus overtime, hours units and card-presence scope. Native CLDR supports Hour; derived forms and full time-tracking paraphrases remain low confidence for native review.
Validation: 17,897 correction checks pass; placeholders and translation preference preserved.
Thanks to xet7 !
2026-09-14: Record 47758fc61, three unflagged repairs, direct native action/noun evidence and low-confidence starred compounds. Original counts unchanged. Correction checks and all three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace two Arabic labels and repair the unflagged starred-list noun. Create Account is directly attested in native MediaWiki; Lists is directly attested in native Mastodon. Starred compounds remain low confidence for native validation.
Validation: 17,892 correction checks pass, preserving placeholders and newer translation preference.
Thanks to xet7 !
2026-09-14: Record cffc0bd98, distinct scopes and low-confidence assignment adaptation. Refresh audit and upcoming changelog counts. Correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace four Arabic/French labels while preserving membership versus assignment, current-card scope and distinct filters. Assignment paraphrase, derived forms and full clauses remain low confidence for native review.
Validation: 17,889 correction checks pass; source placeholders and translation preference preserved.
Thanks to xet7 !
2026-09-14: Record abaa87ed9, action evidence and low-confidence noun paraphrases. Refresh audit counts and upcoming changelog. All correction checks and three summary checks pass.
Thanks to xet7 !
2026-09-14: Record e5625d884, native component evidence, provisional compounds and remaining validation scope. Update short audit and upcoming changelog. All correction checks and three summary tests pass.
Thanks to xet7 !
2026-09-14: Replace two Arabic labels while preserving automatic completion and emoji/member targets. Derive provisional completion wording from native software components; full compounds and reused member terminology remain low confidence for native review.
Validation: 17,879 correction checks pass; placeholders, JSON examples and translation preference preserved.
Thanks to xet7 !
2026-09-14: Record source commit 786d29cfb, native software evidence, low-confidence grammar and remaining validation scope. Refresh audit counts and upcoming changelog. Correction checks and all three summary checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with stronger native lexical evidence for two import hints. Preserve full-phrase review scope and original provenance; three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace the earlier tentative Paste verb in two hints with a directly attested native Dialect control. Preserve original provenance and format identifiers. Full phrases remain low confidence; all 17,876 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with two Tamazight import hint repairs, evidence limits and remaining scope. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace two French hints while preserving Paste your valid data here and literal CSV/TSV or JSON. Paste terminology and full phrasing remain low confidence. All 17,876 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with two unflagged Tamazight stop repairs and remaining terminology review. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace French Stop and Stopping text using native app evidence. Preserve command versus progress; derived full clause and lexical pause/stop overlap remain for fluent review. All 17,874 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with the unflagged Tamazight Resume control repair and remaining review limits. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Use directly attested native Resume terminology for the migration control, preserving resumption rather than completion. Full phrase remains low confidence; all 17,872 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with pause-state repairs, evidence limits and remaining review scope. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with the Tamazight migration progress repair, source evidence limits and remaining scope. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace French progress text using native Start evidence. Preserve ongoing starting, plural migrations and ellipsis; derived passive and full clause remain low confidence. All 17,869 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with the unflagged Tamazight rule qualifier repair and remaining review scope. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace French By qualifier before the rule user field. Complete assembled predicate grammar remains low confidence. All 17,868 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with clarified dictionary authority for prior Tamazight logo repairs. Preserve remaining review scope; three documentation checks pass.
Thanks to xet7 !
2026-09-14: Apply the inspected cross-variety dictionary preface to two earlier logo correction records. Preserve independent native caption evidence and low confidence; no values/counts changed. All 17,867 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with repaired ordering guidance and the dictionary cross-variety preface. Preserve low-confidence review scope; three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace two Arabic values while retaining original ordering and one item per line. Dictionary preface confirms cross-variety proposals; terminology and full wording remain low confidence. All 17,867 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with native evidence limits for the uncertain Tamazight conversion verb. Preserve remaining repair scope; three documentation checks pass.
Thanks to xet7 !
2026-09-14: Distinguish native Return/date-back usage from the proposed checklist conversion verb. Preserve low confidence and the unresolved original-order constraint; no values or counts changed. All 17,865 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with the Tamazight guidance repair, evidence limits and remaining scope. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace Arabic guidance while preserving each line becoming one checklist item. Derived Become and full wording remain low confidence; the original-order variant needs separate review. All 17,865 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with the unflagged Tamazight title correction, evidence limits and remaining scope. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Remove the inherited First qualifier absent from English and preserve editing checklist items as text. Native component evidence supports Edit and Items; full phrase remains low confidence. All 17,864 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit and upcoming notes with two unflagged Tamazight date condition repairs, remaining review limits and verified counts. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace mixed-language conditions and restore When and Set or Changed alternatives. Preserve distinct start and end dates. Set adaptation and full grammar remain low confidence; all 17,863 correction checks pass.
Thanks to xet7 !
2026-09-14: Update the audit and upcoming notes with the Tamazight line-to-item repair, source evidence limits and remaining counts. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace Arabic bulk-entry guidance using native textual Line and Text evidence. Preserve one line equals one checklist item. Full wording remains low confidence; all 17,861 correction checks pass.
Thanks to xet7 !
2026-09-14: Update upcoming notes and audit counts for four repaired Tamazight rule prefixes and their remaining terminology review. Three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace four French prefixes while distinguishing generic and named checklists and items. Native temporal When evidence supports the prefix; checklist terminology and assembled grammar remain low confidence. All 17,860 correction checks pass.
Thanks to xet7 !
2026-09-14: Update the translation audit and upcoming release with the repaired Tamazight label, source commit and remaining review counts. All three documentation checks pass.
Thanks to xet7 !
2026-09-14: Replace the French label with Tamazight using native Text, Below, Logo and Login evidence. Full noun-chain grammar remains low confidence. All 17,856 correction checks pass.
Thanks to xet7 !
2026-09-14: Record custom login logo URL repairs, native terminology evidence and remaining review scope. Changelog and audit progress checks pass. The upcoming release retains the verified wekan22 build repair and Linux arm64 build log.
Thanks to xet7 !
2026-09-14: Replace French labels preserving image/link distinction and URL. Logo has directly labelled zgh community caption evidence; normative authority, bound forms and full phrases remain low confidence. All 17,855 correction checks pass.
Thanks to xet7 !
2026-09-14: Update Audit, TODO Later and Upcoming with 4139001a3 native software evidence and remaining grammar/terminology review. Values/counts unchanged. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: MediaWiki resetpass_announce directly supports complete login beyond temporal ending/legal supplementation. Past actor form and full checklist grammar remain low confidence. Record login noun and unresolved logo terminology. Values/counts unchanged; 17,853 correction checks pass.
Thanks to xet7 !
2026-09-14: Record a536b274a, 15,396 corrected originals, 448 pending findings and 17,853 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French labels preserving plural tags, custom scope, HTML and link/meta element identifiers. Technical semantic extensions and full phrases remain low confidence. All 17,853 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 02cdb84f3, 15,394 corrected originals, 450 pending findings and 17,851 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French Show Checklist at Minicard preserving display action and minicard scope. Proposed checklist/minicard phrases remain low confidence. All 17,851 correction checks pass.
Thanks to xet7 !
2026-09-14: Update Audit, TODO Later and Upcoming with 9de9f2c15 source-context evidence and remaining completion-validation requirements. Values/counts unchanged. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Record native legal supplementation uses of completion root without treating them as proof of past transitive checklist completion. Preserve existing values, counts and low-confidence status. All 17,850 correction checks pass.
Thanks to xet7 !
2026-09-14: Record bd511b086, 15,393 corrected originals, 451 pending findings and 17,850 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace Arabic control preserving Hide and finished-checklist restriction. Derived relative grammar and full phrase remain low confidence for fluent review. All 17,850 correction checks pass.
Thanks to xet7 !
2026-09-14: Record a8ac930ee, 15,392 corrected originals, 452 pending findings and 17,849 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French controls preserving Close Form rather than executing Add/Edit. Derived addition noun and full checklist phrases remain low confidence. All 17,849 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 2544843d6, 15,390 corrected originals, 454 pending findings and 17,847 correction records in Audit, TODO Later and Upcoming. Preserve semantic distinctions and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French activity preserving checklist completion and two ordered %s tokens. Transitive past-completion adaptation and full phrase remain low confidence. Uncompletion requires active reversal wording, not simple negation. All 17,847 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 0ecbc1189, 15,389 corrected originals, 455 pending findings and 17,846 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace four Arabic activities preserving checklist versus item, addition/removal and To/From/In relationships. Preserve exact %s order/count and quotes. Full phrases and derived forms remain low confidence. All 17,846 correction checks pass.
Thanks to xet7 !
2026-09-14: Record ed9620896 and 17,842 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full remaining validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Record edd3ae666 and 17,841 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full remaining validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Use native count and plural element components, preserving literal (0/0). Proposed checklist noun and complete phrase remain low confidence for fluent review. All 17,841 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 0379f9df8 and 17,840 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full remaining validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace three French rule actions preserving Add versus Remove of whole checklist. Proposed checklist term remains low confidence for fluent review. All 17,840 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 3cd6ae3d6 and 17,837 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full remaining validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace six Arabic/French labels preserving singular, plural and Of relation with native list components. Proposed verification noun and full checklist terminology remain low confidence for fluent review. All 17,837 correction checks pass.
Thanks to xet7 !
2026-09-14: Record b0a3b5308, 15,387 corrected original findings, 457 pending findings and 17,831 correction records in Audit, TODO Later and Upcoming. Preserve full validation scope and confidence limits. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Record 0dd39bb6b and 17,829 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full remaining validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace Arabic Add Checklist and French Checklist Actions preserving whole checklist and plural actions. Proposed checklist noun and full grammar remain low confidence. All 17,829 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 79be9d37d, 15,385 corrected originals, 459 pending findings and 17,827 correction records in Audit, TODO Later and Upcoming. Preserve native-source limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French headings preserving single-item versus whole-checklist deletion and questions. Verification noun and full checklist paraphrase remain low confidence; targeted source review does not attest that noun. All 17,827 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 6435ad6a6, 15,384 corrected originals, 460 pending findings and 17,825 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Record 1824cd778 and 17,823 correction records in Audit, TODO Later and Upcoming. Preserve remaining validation scope and confidence limits. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Align two migration status labels with reviewed native migration spelling, preserving status rather than progress/completion. Full noun chain remains low confidence for fluent review. All 17,823 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 5bb209c06, 15,382 corrected original findings, 462 pending findings and 17,821 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and full validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French restriction preserving only board administrators and ability to execute plural migrations. Derived grammar and full authorization sentence remain low confidence for fluent review. All 17,821 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 66c8bd979 and 17,820 correction records in Audit, TODO Later and Upcoming. Preserve confidence limits and remaining validation scope. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French Migration Errors preserving plural errors distinct from warnings. Full software phrase remains low confidence for fluent review. All 17,820 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 41d712523 and 17,819 verified correction records in Audit, TODO Later and Upcoming. Preserve remaining validation scope and confidence limits. Three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace French All Migrations and align Migrations and Migration Steps with reviewed native components. Preserve plural and all semantics. Derived migration plural and full software phrases remain low confidence for fluent review. All 17,819 correction checks pass.
Thanks to xet7 !
2026-09-14: Record 443b180a2 and 17,816 verified correction records in the translation audit, TODO Later and Upcoming. Preserve remaining validation scope and confidence limits. All three metadata checks pass.
Thanks to xet7 !
2026-09-14: Replace Arabic administrator labels and align the singular board administrator role with native MediaWiki administrator terminology. Board-qualified phrase remains low confidence for fluent review. All 17,816 correction checks pass, preserving placeholders and newer translations.
Thanks to xet7 !
2026-09-14: Update audit, TODO Later and Upcoming with c303eb013, 15,381 corrected originals, 463 pending findings and 17,813 correction records. Preserve full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace French Migration Warnings preserving plural warnings rather than errors or failure. Derived plural and full software-migration phrase remain low confidence for fluent review. All 17,813 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit, TODO Later and Upcoming with 3416af191 and 17,812 correction records. Original counts are unchanged; retain full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace French Validate Migration with native verification imperative, preserving validation rather than running or completion. Verification-to-migration adaptation and complete action remain low confidence for fluent review. All 17,812 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit, TODO Later and Upcoming with b84a88696 and 17,811 correction records. Original counts are unchanged; retain full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace three French step labels preserving singular/plural and Current qualifier. Primary native references corroborate step noun and plural; extension to software phases and full agreement remain low confidence for fluent review. All 17,811 correction checks pass.
Thanks to xet7 !
2026-09-14: Update the audit, TODO Later and Upcoming with 858a00526, 15,380 corrected originals, 464 pending findings and 17,808 correction records. Preserve full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Update the audit, TODO Later and Upcoming with 1f72241e3, 15,379 corrected originals, 465 pending findings and 17,805 correction records. Preserve full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace four French completion statuses while distinguishing bare completion from successful migration completion. Completed-tense adaptation, standalone grammar and full success phrase remain low confidence for fluent review. Generic Complete action remains under contextual review. All 17,805 correction checks pass.
Thanks to xet7 !
2026-09-14: Update the audit, TODO Later and Upcoming with 94eb1a0c5, 15,378 corrected originals, 466 pending findings and 17,801 correction records. Preserve full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace five French/Arabic labels with native selection and necessity components, preserving entity scope and required/not-required polarity. Full necessity constructions and software-migration wording remain low confidence for fluent review. Select Color follows native MediaWiki wording. All 17,801 correction checks pass.
Thanks to xet7 !
2026-09-14: Update the audit, TODO Later and Upcoming with 81fba99d7, 15,376 corrected originals, 468 pending findings and 17,796 correction records. Preserve full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace four French migration labels while preserving singular/plural, board/database scope and failed status. Native move noun adapted to software migration, derived plurals and full phrases remain low confidence for fluent review. All 17,796 correction checks pass.
Thanks to xet7 !
2026-09-14: Update the audit, TODO Later and Upcoming with eb3965660, 15,375 corrected originals, 469 pending findings and 17,792 correction records. Preserve full validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace French checkbox, dropdown list and custom-field filter labels with Tamazight components. Preserve selection, dropdown direction and filtering qualifiers. Full control terminology, bound nouns and derived plurals remain low confidence for fluent review. All 17,792 correction checks pass.
Thanks to xet7 !
2026-09-14: Update the audit, TODO Later and Upcoming with 97c1c79fe, 15,374 corrected originals, 470 pending findings and 17,789 correction records. Preserve full validation scope and low-confidence wording. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Update audit evidence, short progress, TODO Later and Upcoming with af33f6640 and 17,785 correction records. Original counts are unchanged; preserve full language-validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Repair Linked Subtask, Linked Card and Linked Board labels using native linked/associated wording. Preserve hierarchy and entity distinctions. Full kanban phrases and participle agreement remain low confidence for fluent review. All 17,785 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit evidence, short progress, TODO Later and Upcoming with b26d1ddc1, 15,373 corrected originals, 471 pending findings and 17,782 correction records. Preserve full language-validation scope and confidence limits. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace two Arabic added-activity messages with local Tamazight past-action and destination wording. Preserve all percent placeholders and subtask hierarchy. Full activity grammar, past conjugation and kanban paraphrase remain low confidence for fluent review. All 17,782 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit evidence, short progress, TODO Later and Upcoming with repair 23c82a5c1, 15,372 corrected originals, 472 pending findings and 17,780 correction records. Preserve broader validation scope and remaining activity/linked-subtask review. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Repair four subtask actions with explicit hierarchical task wording. Remove Language and With from Add Existing Card as Subtask, preserving Existing and As. Preserve confirmation question and plural Actions. Full paraphrases and morphology remain low confidence for fluent review. All 17,780 correction checks pass.
Thanks to xet7 !
2026-09-14: Update audit evidence, progress, TODO Later and Upcoming with f13775594, 15,371 corrected originals, 473 pending findings and 17,776 correction records. Retain full language-validation scope and open existing-card action. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace five Arabic/French subtask labels with explicit Task(s) under a Task wording. Preserve hierarchy, singular/plural, settings and deletion question. Full paraphrases, bound noun morphology and kanban terminology remain low confidence for fluent review. Existing-card action repair remains open. All 17,776 correction checks pass.
Thanks to xet7 !
2026-09-14: Keep the short audit, TODO Later and Upcoming updated with terminology finding 92f69f58d and its unresolved hierarchical wording. Translation values and counts are unchanged. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Identify the unflagged use of Language in Add Existing Card as Subtask. Record indexed primary references and distinguish Work/Task evidence from the still-unverified hierarchical subtask term. Preserve relation semantics during the upcoming repair. No values or counts changed.
Thanks to xet7 !
2026-09-14: Update the audit, TODO Later and Upcoming with repair ef6318121, 15,368 corrected originals, 476 pending findings and 17,771 correction records. Preserve broader validation scope and low-confidence wording. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace French Custom Help Link URL wording with native link and help components. Preserve URL and the custom qualifier. Full noun-chain grammar, bound link noun and specified/custom adaptation remain low confidence for fluent review. All 17,771 correction checks pass.
Thanks to xet7 !
2026-09-14: Record local repair 196edd0f8, 17,770 correction records and remaining full validation scope in the audit, TODO Later and Upcoming notes. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace cross-dialect imseqdacen with the directly attested Standard Moroccan plural inssmrsn for domain account users. Preserve users rather than board members or people. MediaWiki Kabyle confirms the old form and its zgh translations attest the replacement. All 17,770 correction checks pass.
Thanks to xet7 !
2026-09-14: Update Upcoming release notes, TODO Later and the short audit with local repair commit 7a2d1caf4, 17,769 correction records and remaining validation scope. All three changelog and audit-progress checks pass.
Thanks to xet7 !
2026-09-14: Replace two Arabic Board View labels with generic view and singular board wording. The adapted full phrase and bound board noun remain low confidence for fluent Standard Moroccan Tamazight review. All 17,769 audited correction checks pass.
Thanks to xet7 !
2026-09-14: record source fb554131b and 17,767 correction records in the audit and upcoming changelog. Original pending count remains 477; full New User phrasing and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace two Arabic labels with native New adjective and singular account-user wording. Complete New User heading remains low confidence for fluent review. All 17,767 correction checks pass.
Thanks to xet7.
2026-09-14: record source 15481a394, 15,367 corrected originals, 477 pending findings and 17,765 correction records. Full search sentence and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace French instruction preserving writing search text and pressing Enter. Native components support the wording; key-press adaptation, relative clause and full sentence remain low confidence for fluent review. All 17,765 correction checks pass.
Thanks to xet7.
2026-09-14: record source 4ba8d17d4, 15,366 corrected originals, 478 pending findings and 17,764 correction records. Full success/unblock grammar and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace French result while preserving success, singular user and removal of login blocking. Positive success construction, removal nominalization and full bound phrase remain low confidence for fluent review. All 17,764 correction checks pass.
Thanks to xet7.
2026-09-14: record source d0791c6c4, 15,365 corrected originals, 479 pending findings and 17,763 correction records. Full unblock phrases, passive adaptation and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace two French confirmation/result messages preserving All Locked Users and question versus completed-result meaning. Full quantified unblock phrases and passive adaptation remain low confidence for fluent review. All 17,763 correction checks pass.
Thanks to xet7.
2026-09-14: record source 2f4752ff4, 15,363 corrected originals, 481 pending findings and 17,761 correction records. Complete unblock terminology and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace three French click, confirmation and all-user unlock labels by expressing removal of login blocking. Preserve this-user versus all-users scope. Full unblock compounds and grammar remain low confidence for fluent review. All 17,761 correction checks pass.
Thanks to xet7.
2026-09-14: record source 18f7fa766 and 17,758 correction records in the audit and upcoming changelog. Original pending count remains 483; board plural, full phrases and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace four Arabic labels preserving All versus generic Boards and This Board/Card scope. Board plural morphology and full kanban phrases remain low confidence for fluent review. All 17,758 correction checks pass.
Thanks to xet7.
2026-09-14: record source faa68bf87 and 17,754 correction records in the audit and upcoming changelog. Original pending count remains 483; full numeral phrases and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: record source 8dc2224c7, 15,361 corrected originals, 483 pending findings and 17,752 correction records. Update prior subworkspace review status while preserving the new compound and full-phrase confidence limits. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace two French headings with an explicitly derived subworkspace compound, preserving Add versus Name and hierarchy. New compound, bound form, workspace extension and full phrases remain low confidence for fluent review; indexed prefix evidence does not directly attest the compound. All 17,752 correction checks pass.
Thanks to xet7.
2026-09-14: record source 45650996e and 17,750 correction records in the audit and upcoming changelog. Original pending count remains 485; broader validation stays open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace three Arabic labels with native Text, Profile and Delete List wording supported by MediaWiki and Mastodon. Preserve singular list and question punctuation. All 17,750 correction checks pass.
Thanks to xet7.
2026-09-14: record direct CLDR evidence 5610dff52 and full calendar terminology limits in the audit and upcoming changelog. Counts remain 485 pending originals and 17,747 correction records. All three metadata tests pass.
Thanks to xet7.
2026-09-14: directly review current CLDR Bambara date fields and missing localized calendar variant names. Era vocabulary does not establish reference-date Epoch; retain both tabular calendar findings pending full terminology review. No translation values or counts changed.
Thanks to xet7.
2026-09-14: record evidence 2219d5358 in the audit and upcoming changelog. Counts remain 485 pending originals and 17,747 correction records; direct PDF, full command and subworkspace review remain open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: expanded indexed conjugation excerpt distinguishes plain bdu Begin/Start from emphatic bdu Share/Divide. Record printed page 94 and direct PDF redirect limits; full command and subworkspace terminology remain under review. No locale values or counts changed. All 17,747 correction checks pass.
Thanks to xet7.
2026-09-14: record source f16fae64a, 15,359 corrected original findings, 485 pending findings and 17,747 correction records. Complete command, indexed-only evidence and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace French start heading, preserving the Planning Poker feature name and distinguishing the action from the Start date noun. Indexed conjugation evidence and full command remain low confidence: the manual currently redirects to HTML and needs direct/fluent review. All 17,747 correction checks pass.
Thanks to xet7.
2026-09-14: record source fea294be0, 15,358 corrected original findings, 486 pending findings and 17,746 correction records. Full workspace terminology and broader validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace French Workspace menu with native Menu and content-space components. Organizational workspace extension and complete bound phrase remain low confidence for fluent review. All 17,746 correction checks pass.
Thanks to xet7.
2026-09-14: record source ad526816b and 17,745 correction records in the audit and upcoming changelog. Original pending count remains 487; full kanban phrases and broader translation validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: record source a06565956 and 17,741 correction records in the audit and upcoming changelog. Original pending count remains 487; morphology and broader translation validation stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace six Arabic user/member/list labels using reviewed native terminology. Preserve distinct singular object types; the derived free-state Member noun remains low confidence for morphology review. All 17,741 correction checks pass.
Thanks to xet7.
2026-09-14: record source 82ba97005 and 17,735 correction records in the audit and upcoming changelog. Original pending count remains 487; broader translation validation stays open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace three Arabic date predicate labels with exact CLDR native singular date-field names. Preserve date-unit meaning across tooltips, Gantt, calendar navigation and search. All 17,735 correction checks pass.
Thanks to xet7.
2026-09-14: record source aef5ea20a and 17,732 correction records in the audit and upcoming changelog. Original pending count remains 487; broader translation validation stays open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace six Arabic People, Edit Profile, Title, Calendar, Lists and Members labels with native terminology supported by Mastodon, MediaWiki and CLDR. Preserve action, calendar and plural scope. All 17,732 correction checks pass.
Thanks to xet7.
2026-09-14: record source e9f1b33b9 and 17,726 correction records in the audit and upcoming changelog. Original pending count remains 487; full phrase and broader translation review stay open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace three French headings using native Edit terminology, preserving singular team/user objects and the Planning Poker name. Complete adapted phrases remain low confidence and need fluent review. All 17,726 correction checks pass.
Thanks to xet7.
2026-09-14: update the audit and upcoming changelog with source cf0a2f19b and 17,723 correction records. Original pending findings remain 487; broader translation validation remains open. All three metadata tests pass.
Thanks to xet7.
2026-09-14: replace the Arabic People label with the native equivalent documented in Mastodon zgh. Preserve generic people scope rather than users or board members. All 17,723 correction checks pass.
Thanks to xet7.
2026-09-14: record source fix 67dbacc28 and update the audit and upcoming changelog to 15,357 corrected original findings, 487 pending findings, and 17,722 correction records. Full calendar naming and the remaining translation review stay open. Correction checks and all three metadata tests pass.
Thanks to xet7.
2026-09-14: Use the native Calendar noun and preserve the Minguo calendar name from English source, avoiding generic Chinese language/calendar substitution. LOW CONFIDENCE full mixed-script naming needs fluent review. All 17,722 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with directly verified authentication source provenance. Locale values and counts remain unchanged; three metadata test entries pass. Full terminology review continues.
Thanks to xet7 !
2026-09-14: Direct dictionary extraction shows authentication terms marked MC£, whereas the search index renders MCF. The bibliography identifies Tuareg sources, so do not accept the candidate as Moroccan attestation. Preserve authentication, method/type, display and default scope; keep findings pending.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with two heading repairs and full-phrase review limits. All 17,721 correction/rendering checks and three metadata test entries pass; 488 originals and broader language validation remain open.
Thanks to xet7 !
2026-09-14: Replace two Arabic headings, preserving singular Board Title and plural Details of a singular Card. Native title/details vocabulary is supported; LOW CONFIDENCE complete kanban phrases and bound forms require fluent review. All 17,721 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with two software-label repairs and server-heading review limits. All 17,719 correction/rendering checks and three metadata test entries pass; 488 originals and broader validation remain open.
Thanks to xet7 !
2026-09-14: Replace two Arabic software labels, preserving Server Error heading and Closed status rather than Close action. Native components support the error heading; LOW CONFIDENCE complete server phrase requires fluent review. All 17,719 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with three member/board label repairs and remaining full-phrase uncertainty. All 17,717 correction/rendering checks and three metadata test entries pass; 488 originals and broader language validation remain open.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with six Add repairs and full-phrase review limits. All 17,714 correction/rendering checks and three metadata test entries pass; 488 originals and broader language validation remain open.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with minutes/seconds repairs and remaining seconds-plural uncertainty. All 17,708 correction/rendering checks and three metadata test entries pass; 488 originals and broader language validation remain open.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with five reference-supported date/time labels. All 17,706 correction/rendering checks and three metadata test entries pass; 488 originals and broader language validation remain open.
Thanks to xet7 !
2026-09-14: Replace five Arabic labels using full native CLDR weekday names and reference-supported plural days/hours. Preserve weekday identity and duration plural scope. All 17,706 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with five unflagged interface repairs. All 17,701 correction/rendering checks and three metadata test entries pass; 488 originals and broader language validation remain open.
Thanks to xet7 !
2026-09-14: Replace five Arabic interface labels with native software wording. Preserve Back versus previous-page adjacency, next versus previous, confirmation acknowledgment and generic Settings scope. All 17,701 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with the source-checked invitation rejection action. All 17,696 correction/rendering checks and three metadata test entries pass; 488 originals and wider language validation remain open.
Thanks to xet7 !
2026-09-14: Replace the French Decline invitation button using the native request-rejection imperative. Source handlers confirm rejection rather than closing the popup. All 17,696 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with two deletion repairs and full-phrase review limits. Record 15,356 originals corrected, 488 pending and 17,695 correction records. Correction/rendering and three metadata test entries pass; wider language validation remains open.
Thanks to xet7 !
2026-09-14: Replace the French workspace deletion question and Delete Board action. Preserve certainty, singular this-workspace object and deletion rather than archive. LOW CONFIDENCE complete workspace question and kanban board phrase require fluent review. All 17,695 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with three repairs and remaining full-heading uncertainty. Record 15,355 originals corrected, 489 pending and 17,693 correction records. Correction/rendering and three metadata test entries pass; broader language validation remains open.
Thanks to xet7 !
2026-09-14: Replace two French Workspace Settings headings and the Arabic Close action. Native software references support settings and close; LOW CONFIDENCE full workspace headings and bound-state terminology remain subject to fluent review. All 17,693 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update short audit, TODO Later and Upcoming with five workspace corrections and remaining terminology uncertainty. Record 15,353 originals corrected, 491 pending and 17,690 correction records. Correction/rendering and three metadata test entries pass; wider language validation remains open.
Thanks to xet7 !
2026-09-14: Replace five French workspace values, retaining add versus edit and singular workspace-name scope. Native institutional usage corroborates the existing space noun. LOW CONFIDENCE WeKan workspace extension, bound form and full labels require fluent review; subworkspace remains separate. All 17,690 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update the short audit, TODO Later and Upcoming with the native software confirmation button repair. All 17,685 correction/rendering checks and three metadata test entries pass; 496 originals and wider validation remain open.
Thanks to xet7 !
2026-09-14: Replace the Arabic Confirm label with the native software confirmation-button wording. Keep acknowledgment distinct from invitation acceptance and confirmation questions. All 17,685 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update the short translation audit, TODO Later and Upcoming with the source-supported singular page label. All 17,684 correction/rendering checks and three metadata test entries pass; 496 originals and wider language validation remain open.
Thanks to xet7 !
2026-09-14: Use the exact native MediaWiki singular Page noun, retaining scope and avoiding claims about other regional synonyms or full page phrases. All 17,684 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update audit summary, TODO Later and Upcoming with the native Ethiopic base repair and retained era distinction. Record 15,348 originals corrected, 496 pending and 17,683 correction records. Correction/rendering and three metadata test entries pass; complete language validation remains open.
Thanks to xet7 !
2026-09-14: Use the CLDR native Ethiopic calendar base while preserving the Amete Alem era variant name. LOW CONFIDENCE composed mixed-script label remains subject to fluent review. All 17,683 correction/rendering checks pass.
Thanks to xet7 !
2026-09-14: Update the short audit, TODO Later and Upcoming with the email-invitation correction and its remaining dialect uncertainty. All 17,682 correction/rendering checks and three metadata test entries pass; the original pending queue remains 497.
Thanks to xet7 !
2026-09-14: Replace the remaining French email-invitation button using the existing Invite action and native email term, preserving the email channel. LOW CONFIDENCE invitation verb and full instrumental phrase; renewed Moroccan dialect review remains required following the CNAM provenance correction. All 17,682 correction and rendering checks pass.
Thanks to xet7 !
2026-09-14: Update the short translation audit, TODO Later and Upcoming with the reference follow-up. Preserve all 497 pending originals and the wider validation scope. Three changelog and audit-progress test entries pass.
Thanks to xet7 !
2026-09-14: Corroborate regional human computer-database usage and distinguish it from the Polish article wrapper. Keep the raw-file qualifier and complete label pending; record retrieval limits without treating missing evidence as a language error.
Thanks to xet7 !
Update dated audit and Upcoming with unflagged repair and 17681 correction records. Explicitly retain terminology review in cron and recovery contexts. Three metadata test entries pass.
Replace French with existing recovery severity wording for identical source. Terminology remains low confidence and needs fluent review in both contexts; local consistency is not linguistic validation. All 17681 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with three repairs, 17680 correction records and 497 pending originals. Keep full phrase and wider language validation visible. Three metadata test entries pass.
Preserve add, remove from and display on minicard cover distinctions. Local cover sense and full phrases remain low confidence pending fluent review. All 17680 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with two unflagged repairs, 17677 correction records and remaining language validation requirements. Three metadata test entries pass.
Preserve imperative upload versus completed upload state using native action vocabulary and local profile-picture terminology. Passive morphology and full phrases remain low confidence pending fluent review. All 17677 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with three unflagged repairs, 17675 correction records and remaining language validation requirements. Three metadata test entries pass.
Replace three Arabic and French titles using local profile-picture vocabulary and native actions. Full profile terminology remains low confidence pending fluent review. All 17675 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Link dated terminology evidence in audit and Upcoming while keeping unresolved full instructions visible. Three metadata test entries pass; no locale values changed.
Separate native server/error vocabulary from indexed cross-dialect execution and installation terms. Preserve command and installation scope requirements; no locale values or counts changed.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with source repair, 17672 correction records and 500 pending originals. Keep full phrase and wider language validation visible. Three metadata test entries pass.
Use native calendar noun while preserving Dangi and exact ISO-8601 names. Full mixed-script composition remains low confidence pending fluent review. All 17672 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with source repair, 17670 correction records and 501 pending originals. Retain provisional CLDR and wider language review requirements. Three metadata test entries pass.
Update dated audit and Upcoming with unflagged repair and 17669 correction records. Keep 502 pending originals and wider language validation visible. Three metadata test entries pass.
Replace French with native name and list vocabulary. Complete kanban noun phrase remains low confidence pending fluent review. All 17669 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with source repair, 17668 correction records and 502 pending originals. Keep wider language validation requirements visible. Three metadata test entries pass.
Retain support information, not yet and added action using native component vocabulary. Full negative passive phrase remains low confidence pending fluent review. All 17668 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with three unflagged repairs and 17667 verified correction records. Keep 503 pending originals and broader language validation visible. Three metadata test entries pass.
Update dated audit and Upcoming with repair commit, 17664 correction records and 503 pending originals. Keep broader language validation requirements visible. Three metadata test entries pass.
Replace Arabic CPU consumption wording with CPU count using native count vocabulary. Retain conventional OS and CPU abbreviations. Full mixed-script label remains low confidence pending fluent review. All 17664 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with repair commit and 17663 correction records. Keep 504 pending originals and wider language validation visible. Three metadata test entries pass.
Retain exact predicate code and cards with an end date, without implying completed or overdue cards. Full relative construction remains low confidence pending fluent review. All 17663 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with repaired board/card scope, 17662 correction records and 505 pending originals. Wider language review remains open. Three metadata test entries pass.
Preserve adding board members to the card or removing them from the card, without implying removal from the board. Full coordinated instruction remains low confidence pending fluent review. All 17662 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with repair commit and 17661 correction checks. Keep 506 pending originals and wider fluent review visible. Three metadata test entries pass.
Update dated audit and Upcoming with 17660 correction records, source commit and 506 pending originals. Retain full phrase and broader language review requirements. Three metadata test entries pass.
Preserve support information restricted to logged-in users only. Native components support provisional wording; derived participle and full sentence remain low confidence pending fluent review. All 17660 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with four unflagged repairs and 17659 verified correction records. Keep 507 pending original findings and broader language review requirements visible. Three metadata test entries pass.
Replace four Arabic and French support labels with native assistance vocabulary. Preserve title and content distinctions. Full noun phrase composition remains low confidence pending fluent review. All 17659 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update 2026-09-14 audit and Upcoming with repair commit, 17655 correction checks and 507 pending original findings. Broader fluent review remains required. Three metadata test entries pass.
Preserve the named estimation technique, this deletion question and change vote end-date action. Full composition remains low confidence pending fluent review. All 17655 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update dated audit and Upcoming with repair commit and 509 pending original findings. Preserve astronomical epoch and broader language review requirements. Three metadata test entries pass.
Record the 2026-09-14 voting repair commit, 17652 verified corrections and unchanged 510 original pending findings. Retain fluent review, restored-value and provenance review limitations. Three metadata test entries pass.
Replace four Arabic and French voting labels with consistent Tamazight wording. Preserve question, edit and deletion actions. Election terminology adapted to card voting and complete phrases remain low confidence pending fluent review. All 17652 correction checks pass.
Reviewed 2026-09-14. Thanks to xet7.
Update audit and upcoming changelog on 2026-09-14 with 510 pending originals. Preserve terminology confidence limits and record passing structural checks.
Replace French title on 2026-09-14 while preserving change-date action. Native components support provisional wording; mark election-to-card-voting and complete syntax as low confidence.
Replace French heading after native vocabulary review on 2026-09-14. Mark institutional directives to usage guidance adaptation as low confidence pending fluent review.
Record direct Moroccan RAM terminology usage on 2026-09-14 for three memory records. Preserve low-confidence flags because website translation provenance and full diagnostics grammar remain unverified. No locale values changed.
Record dated 2026-09-14 attribution correction and renewed terminology review in upcoming release notes and TODO Later. Preserve unchanged pending counts and distinguish structural tests from fluency.
Review CNAM bibliography on 2026-09-14 and correct source notes in 98 translation records. MC£ denotes Tuareg sources and MC denotes Mokrane Chemim, not Central Moroccan dialect codes. Retain affected terminology for renewed review without altering locale values.
Replace French wording on 2026-09-14 while preserving current qualifier and date placeholder. Record deadline terminology and full status syntax as low confidence pending review.
Update audit and upcoming release notes on 2026-09-14 with 513 pending originals. Record restored sighting qualifier, passing structural checks and remaining full-language validation.
Restore the omitted sighting qualifier and native calendar wording on 2026-09-14. Preserve country identity and mark moon-sighting composition as low confidence pending fluent review.
Compare directly downloaded publisher and GNU dictionary copies on 2026-09-14. Corroborate Coptic spelling and retain Hijri variants pending legible tabular, epoch and sighting terminology. Record extraction conflicts without treating indexed text as complete validation.
Update audit and upcoming changelog on 2026-09-14 with 514 pending originals. Record dictionary evidence, extraction limitation, passing checks and remaining fluent review.
Replace English-only label using Dzongkha computing dictionary vocabulary on 2026-09-14. Preserve Coptic identity and record full compound spelling as low confidence pending language review.
Update audit and upcoming changelog on 2026-09-14. Record 515 pending originals, one additional unflagged repair, passing checks and remaining language validation.
Replace Arabic and French labels using native announcement vocabulary on 2026-09-14. Keep full administrator attribution syntax low confidence and retain separate system-wide active finding for review.
Update audit and upcoming release notes on 2026-09-14. Record 516 pending originals and unresolved free-memory terminology, with passing structural checks.
Replace French Node memory usage label on 2026-09-14. Preserve external qualifier without implying external storage; mark full mixed-source adaptation low confidence.
Replace French setting text after native vocabulary review on 2026-09-14. Preserve creator ownership and existing terminology, with complete card label adaptation marked low confidence.
Update audit summary and upcoming release notes on 2026-09-14. Record 518 pending originals, passing structural checks and remaining fluent language validation.
Replace Arabic OS total-memory label on 2026-09-14 using native total vocabulary and Moroccan computing terminology. Preserve total versus free memory distinction and mark full adaptation low confidence.
Update audit and upcoming release notes on 2026-09-14 with 519 pending original findings and explicit low-confidence grammar review. Correction and metadata tests pass.
Replace French status text after native vocabulary review on 2026-09-14. Mark positive completion morphology and full status sentence as low confidence pending fluent review.
Update audit progress and upcoming changelog on 2026-09-14. Record the three refined email commands, passing correction checks, unchanged pending counts and remaining language review.
Use the native MediaWiki imperative in three email bodies after reference review on 2026-09-14. Preserve placeholders and keep complete email wording under low-confidence language review.
Update translation audit progress and upcoming release notes on 2026-09-14. Record 520 remaining original findings and preserve the wider language validation scope.
Replace French diagnostics label with native usage and documented computer-memory components. Full nominal adaptation remains low confidence. All 17,637 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked repair and 521 pending originals. Custom-field and complete language review remain open. Changelog and audit-progress checks pass.
Replace French conditional prompt while preserving already-existing account. Native possession/conditional components support vocabulary; full clause remains low confidence. All 17,636 correction regressions pass.
Update audit, TODO Later and Upcoming with unflagged repair and remaining archive/imperative review. Original pending count remains 522. Changelog and audit-progress checks pass.
Update audit, TODO Later and Upcoming with source-linked repair and 522 pending originals. Full language verification remains open. Changelog and audit-progress checks pass.
Replace French error message while preserving error during attempted login without inventing a password or LDAP cause. Record temporal-clause uncertainty. All 17,634 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked repairs and 523 pending originals. Full language verification remains open. Changelog and audit-progress checks pass.
Replace French checking labels while preserving separate file-attachment and member-avatar scopes. Record derived action noun and complete ownership uncertainty. All 17,633 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked repairs and 525 pending originals. Full language verification remains open. Changelog and audit-progress checks pass.
Replace Arabic open action and many-cards-at-once label. Preserve imperative, multiple cards and one-operation qualifier. Record verb and full-phrase uncertainty. All 17,631 correction regressions pass.
Keep numeric sum distinct from addition operation, count and financial amount. Record reference limitations and failed full-PDF fetch without changing translation values or counts. Changelog and audit-progress checks pass.
Update audit, TODO Later and Upcoming with source-linked maximum-size repairs and 526 pending originals. Full language verification remains open. Changelog and audit-progress checks pass.
Replace Arabic avatar and upload file-size labels, preserving maximum, byte units and distinct scopes. Record mathematical-term adaptation and composed noun uncertainty. All 17,629 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked minimum-length repair and 528 pending original findings. Full language validation remains open. Changelog and audit-progress checks pass.
Replace French warning while preserving required minimum of three characters and username scope. Record full-composition uncertainty. All 17,627 correction regressions pass.
Update audit, TODO Later and Upcoming with unflagged correction and remaining passive/assignee review. Original pending count remains 529. Changelog and audit-progress checks pass.
Replace French Removed from while preserving passive event and source relation. Record finite-passive uncertainty; assignee terminology remains distinct and unresolved. All 17,626 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked repairs and 529 pending originals. Full language verification remains open. Changelog and audit-progress checks pass.
Replace French move fragments while preserving another-list destination and when-event scope. Record derived passive and agreement uncertainty. All 17,625 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked move/restore repairs and 530 pending findings. Keep full language validation open. Changelog and audit-progress checks pass.
Replace French messages using native move/restore components. Preserve old and new board locations and restore destination, with every placeholder intact. Full phrasing remains low confidence. All 17,623 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked corrections and 532 pending original findings. Preserve broader fluent review scope. Changelog and audit-progress checks pass.
Replace French activity and Arabic removal control. Preserve member removal from card and all nested location placeholders. Native remove/member components are supported; complete activity wording remains low confidence. All 17,621 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked repair and 533 pending original findings. Preserve full-language and clipboard terminology review scope. Changelog and audit-progress checks pass.
Replace French warning with native text and negative-validity components, retaining JSON format. Complete construction remains low confidence; paste prompts remain open because clipboard terminology was not established. All 17,619 correction regressions pass.
Update audit, TODO Later and Upcoming with source-linked repair, 15,310 corrected originals and 534 pending. Language validation remains open. Changelog and audit-progress checks pass.
Replace French display label with native show/member components and existing avatar terminology. Preserve ownership by board members; full wording remains low confidence. All 17,618 correction regressions pass.
Update audit, TODO Later and Upcoming with five source-linked corrections and 535 pending original findings. Keep full language validation open. Changelog and audit-progress checks pass.
Replace five French or Arabic popup and activity messages. Preserve start, end and received dates and destination-date/card placeholder roles. Record full-phrase and actor morphology uncertainty. All 17,617 correction regressions pass.
Update audit, TODO Later and Upcoming with the repair source and 15,306 corrected originals, 538 pending findings. Preserve low-confidence review scope. Changelog and audit-progress checks pass.
Replace two French repair labels using the documented correction verb, retaining URL and existing avatar terminology. Complete wording remains low confidence pending language review. All 17,612 correction regressions pass.
Link the Tamazight popup repair and update audit, TODO Later and Upcoming counts to 15,304 corrected originals and 540 pending. Keep fluent review and restored-value validation open. Changelog and progress checks pass.
Replace French popup title while retaining Excel CSV/TSV names. Record native entry imperative and cached import terminology evidence with import-specific wording still low confidence. All 17,610 correction regressions pass.
Update short audit, TODO Later and Upcoming with source-linked Saudi sighting fix, provisional-source issues and unresolved epoch/fluency scope. Track 15,303 corrected originals and 541 pending findings. Changelog and audit-progress checks pass.
Replace English label with reference-supported Fulah components and retain moon-sighting distinction. Record provisional CLDR punctuation issue, reject Swedish homograph as evidence and retain full technical-language uncertainty. All 17,609 correction checks pass.
Update short audit, TODO Later and Upcoming with source-linked native Adlam names, Latin transcription caveats and remaining Hijri variant scope. Track 15,302 corrected originals and 542 pending findings. Changelog and audit-progress checks pass.
Transcribe full native calendar names into the Latin ff translation instead of bare English adjectives. Record exact Adlam source and low-confidence cross-script/regional transcription caveats. Three Hijri variant findings remain pending. All 17,608 correction checks pass.
Update short audit, TODO Later and Upcoming with explicit lack of canonical native attestation and remaining epoch/fluency scope. Track 15,300 corrected originals and 544 pending findings. Mechanical correction, changelog and audit-progress checks pass.
Restore calendar noun in two bare English labels using existing Bambara construction and provisional borrowed/proper names. Explicitly record lack of canonical native attestation, low-confidence spelling and composition, and unresolved epoch variants. All 17,606 mechanical correction checks pass.
Update short audit, TODO Later and Upcoming with source-linked repairs and explicit unresolved technical-meaning/grammar caveats. Track 15,298 corrected originals and 546 pending findings. Mechanical checks do not prove fluency; wider validation remains open. Changelog and audit-progress checks pass.
Replace four French findings. Preserve duplicate and empty qualifiers using provisional repeat-derived and contains-nothing wording. Avoid private/double lexical ambiguity; record unresolved technical term and grammar explicitly. All 17,604 correction checks pass.
Update short audit, TODO Later and Upcoming with source-linked URL scope repairs and full language-validation caveats. Track 15,294 corrected originals and 550 pending findings. Changelog format, release placement and audit-progress checks pass.
Replace two French findings, preserving all-file versus attachment URL scope and correction action. Record exact lexicon references and dialect, acronym and noun-relation caveats. All 17,600 correction checks pass.
Update short audit, TODO Later and Upcoming with source-linked missing-list/ID and file-URL repairs. Track 15,292 corrected originals and 552 pending findings. Preserve wider language-validation scope. Changelog format, release placement and audit-progress checks pass.
Replace four French findings, preserving create/fix, missing lists/IDs and file-URL correction scope. Record native and dialect-specific references with derived negative-plural grammar caveats. All 17,598 correction checks pass.
Update short audit, TODO Later and Upcoming with three unflagged source-linked repairs. Keep original pending counts unchanged and retain full language-validation scope. Changelog format, release placement and audit-progress checks pass.
Preserve both ordered %s tokens, attachment event meaning, upload direction and by-actor versus at-time headers. Record native roots with derived conjugation and dialect caveats. All 17,594 correction checks pass.
Update short audit, TODO Later and Upcoming with source-linked count/filesystem fixes and low-confidence adaptation caveats. Track 15,288 corrected originals and 556 pending findings. Changelog format, release placement and audit-progress checks pass.
Replace four French/Arabic messages. Preserve minicard count, singular/all/all-of-board attachment scope and filesystem destination. Record explicit lexicon references with dialect and grammar caveats. All 17,591 correction checks pass.
Update short audit, TODO Later and Upcoming with eight source-linked repairs and exact scope caveats. Track 15,284 corrected originals and 560 pending findings. Changelog format, release placement and audit-progress checks pass.
Replace eight French/mixed-language values. Preserve deleted action, exact %s, when fragment, personal ownership, all versus all-of-board scope and GridFS/S3 destinations. Record dialect and composition caveats. All 17,587 correction checks pass.
Update short audit, TODO Later and Upcoming with source-linked attachment repairs, nine unflagged fixes and explicit dialect caveats. Track 15,278 corrected originals and 566 pending findings. Changelog format, release placement and audit-progress checks pass.
Update short audit, TODO Later and Upcoming with field scope, low-confidence grammar and source-linked correction evidence. Track 15,275 corrected originals and 569 pending findings. Changelog format, release placement and audit-progress checks pass.
Preserve field-label/minicard scope and visible-only-to-board-admin restriction. Include the unflagged unclear visibility translation and record native components with low-confidence grammar caveats. All 17,567 correction checks pass.
Update short audit, TODO Later and Upcoming with current counts and source-linked title repairs. Preserve low-confidence and broader validation scope. Changelog format, release placement and audit-progress checks pass.
Replace three French findings while preserving all-board scope, Trello import direction and received date distinct from other dates. Record native component references and low-confidence software composition. All 17,565 correction checks pass.
Update short audit, TODO Later and Upcoming with source-linked evidence, native display/index distinction and low-confidence grammar caveats. Track 15,271 corrected originals and 573 pending findings. Changelog format, release placement and audit-progress checks pass.
Preserve added qualifier, plural team/organization scope and displayed-below relation. Reference native addition and display components without confusing indexed with displayed. Record derived agreement and dialect caveats. All 17,562 correction checks pass.
Update the short audit, TODO Later and Upcoming source-linked entry. Track 15,269 corrected originals and 575 pending findings, including 432 Tamazight. Preserve wider validation scope and low-confidence caveats. Changelog format, release placement and audit-progress checks pass.
Replace four French findings, preserving removal from a board and contact-administrator creation instructions. Record native component references and low-confidence conjugation, dialect and full-phrase caveats. Verify all 17,560 audited corrections, rendering and placeholder invariants.
Update dated source commit, verified correction inventory and remaining findings in Audit, TODO Later and Upcoming. Preserve the open grammar, fluency and broader validation scope.
Update dated source commit, verified correction inventory and remaining findings in Audit, TODO Later and Upcoming. Keep uncertain spelling and grammar plus wider validation open.
Replace French and preserve opposite left/right directions and selected-list scope. Native direction vocabulary is reference-supported; emphatic spelling, bound forms and full phrase agreement remain low confidence pending fluent review.
Update dated source commit, correction inventory and remaining original findings in Audit, TODO Later and Upcoming. Retain the open fluency and broader validation scope.
Refresh dated source commit, exact correction inventory and remaining findings in Audit, TODO Later and Upcoming. Preserve the open full-language validation scope.
Update dated source commit, exact correction inventory and remaining findings in Audit, TODO Later and Upcoming. Preserve the open dialect, fluency and wider validation scope.
Update dated source commit and exact correction inventory in Audit, TODO Later and Upcoming. Keep uncertain terminology and broader language validation open.
Replace Arabic activity and template labels, restore the omitted notification meaning and preserve body versus subject. Activity terminology adaptation, bound forms and full label chains remain low confidence pending fluent review.
Update dated source commit, exact correction inventory and remaining findings in Audit, TODO Later and Upcoming. Keep uncertain phrases and broader language validation open.
Update dated source commit, correction inventory and remaining audit findings. Group the five Upcoming translation entries and refresh their overview. Preserve the open fluency and broader validation scope.
Update dated source commit, correction inventory and remaining findings in Audit, TODO Later and Upcoming. Keep uncertain grammar and broader validation open.
Replace three French failure, attempt-error and SMTP success messages. Preserve negative versus affirmative result and user ownership. Derived sending noun, affirmative success predicate and full sentences remain low confidence pending fluent review.
Refresh dated Audit, TODO Later and Upcoming notes with the verified correction inventory and remaining findings. Keep full-language validation and uncertain phrasing open.
Replace three French values. Preserve existing-account correct-username/wrong-password versus nonexistent-username cases and multiple-operator capability. Account predicates, agreement and full phrases remain low confidence pending fluent review.
Update the dated audit source commit and correction inventory, refresh TODO Later counts and add Upcoming search translation notes. Preserve the open full-language validation scope.
Replace French and correct the mistaken optional interpretation of OR. Preserve any versus all condition scopes, example names and operator tokens. Full logical phrases and return conjugations remain low confidence pending fluent review.
Create Upcoming notes for the rule report and popup source commit after the new release. Refresh TODO Later validation status while leaving published release notes unchanged.
Record the dated source commit and verified correction inventory in Audit, TODO Later and Upcoming. These three unflagged repairs leave the original pending count unchanged; wider language validation remains open.
Replace French report and details and correct rule terminology in import/export. Preserve singular report and plural rules and both transfer actions. Import imperative derivation and full software phrasing remain low confidence pending fluent review.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Update dated translation audit counts, TODO Later and Upcoming notes. Move five post-release translation entries from v11.75 to Upcoming because that release does not contain their commits. Preserve their descriptions and keep language validation open.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Replace French and Arabic values and distinguish the IRCAM rule noun from regular. Preserve singular and plural roles, board ownership and rule-title input. Software adaptation and complete phrases remain low confidence pending fluent review.
Update the dated source commit, verified correction inventory and remaining findings in Audit, TODO Later and Upcoming notes. Preserve the open language-validation scope.
Replace French while preserving opening and closing body tags and opposite insertion directions. Custom qualifier adaptation and full phrase composition remain low confidence pending fluent review.
Update dated source commit and exact correction inventory in the audit, TODO Later status and Upcoming notes. Keep uncertain phrasing and wider validation explicitly open.
Replace seven French and Arabic labels and activity fragments using native start and expiration components. Preserve old versus new time placeholders. Generic calendar adaptation and full activity composition remain low confidence pending fluent review.
Record the dated source commit, verified correction inventory and remaining original findings. Refresh the TODO Later status and Upcoming translation notes while retaining the open fluency and wider validation scope.
Replace French in both received-time activity fragments. Preserve current and previous time placeholders and destination direction. Reception terminology from the mixed-source computing lexicon and full phrase composition are low confidence pending fluent review.
Identify the saved v11.75 missing-Moment error as already repaired. Record the fresh Linux arm64 Meteor bundle build and passing assignee, calendar and release-preflight regressions in Upcoming notes. Keep translation audit progress unchanged during build verification.
Preserve operator classification and required versus received value, retaining format tokens exactly. Mathematical terminology adaptation, derived forms and full diagnostic phrasing remain low confidence pending review.
Replace French and Arabic while preserving status choices, date versus time validation and exact format tokens. Derived forms and complete diagnostics remain low confidence pending review.
Preserve member versus creator and board versus list title matching, retaining executable operator tokens. Complete relative clauses, plural and possessive agreement remain low confidence pending fluent review.
Replace French and mixed-script text while preserving sort direction, card versus board scope, export restrictions and literal format names. Complete noun and capability phrasing remains low confidence pending fluent review.
Replace French options/items instructions, keeping Enter as the physical key and preserving action scopes. Complete keyboard phrasing and inherited item terminology remain low confidence. All 17,413 correction checks pass.
Preserve ISO week-of-year, selectable first weekday and All Boards page display distinctions with native components. Full genitive and selection phrases remain low confidence. All 17,411 correction checks pass.
Replace Arabic/French using directly attested native sort terminology, preserving the format token and invalid-sort meaning. Full diagnostic composition remains low confidence. All 17,408 correction checks pass.
Repair Arabic/French role descriptions while preserving posting, comment visibility and read-only viewing/edit restrictions. Full capability conjugations and role composition remain low confidence. All 17,406 correction checks pass.
Replace French permission and board-role errors, retaining signed-in users, board membership and board administrator distinctions. Full conjugation and role/genitive composition remain low confidence. All 17,403 correction checks pass.
Replace French in six sample values while retaining JSON property names, three-card order and first/second/last identification. Full card genitives and derived feminine agreement remain low confidence. All 17,400 correction checks pass.
Repair six French labels with consistent first/last place wording, preserving add/move and own/selected list distinctions. Native components are reference-supported; full software phrases and possessive composition remain low confidence. All 17,399 correction checks pass.
Use native Tifinagh deletion wording, translate custom-field confirmation and member-removal activity, and preserve member/board placeholders. Full custom-field and activity composition remain low confidence. All 17,393 correction checks pass.
Use a directly attested native Subject label and compose scoped current-card member wording. Full card/board composition remains low confidence. All 17,390 correction checks pass, including exact placeholder and newer-translation preference coverage.
Record successful Linux arm64 bundle compilation, regression coverage and remaining browser/platform verification limits. Document the read-only Upcoming notes check.
Use existing native date formatting instead of the removed Moment dependency. Check real Upcoming entries before release tool installation or mutations, including explicit version overrides. Cover missing, empty and duplicate notes with read-only regression tests.
Replace French with native component wording and preserve the site-name placeholder. Full email phrasing, possessive attachment and verification verb dialect spelling remain low confidence.
Replace French labels while keeping unknown distinct from none and selection color distinct from label creation. Complete phrases, derived noun forms and dropdown-option sense remain low confidence.
Replace French field settings and the Arabic change-date popup title. Preserve new-card versus all-card scope. Full phrases, software-field usage and derived card forms remain low confidence.
Replace Arabic and French with native create/edit/date vocabulary and IRCAM-attested field terminology. Keep button and popup creation wording consistent. Full software-field phrasing and bound date composition remain low confidence.
Replace French notification labels and the incorrect image noun in the unread-comments tooltip. Preserve opposite read/unread states. Full command phrasing and inherited passive-read inflection remain low confidence despite reference-supported component vocabulary.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Replace four French values. Native sources attest remove, all, member and error components, including the error plural in the CNDH Amazigh memorandum. Full command phrasing, card compounds and software-error usage remain low confidence.
Replace three French labels while preserving import-member selection, full-card list display and per-list card counts. Native component vocabulary is reference-supported; complete phrases, derived bound forms and kanban card terminology remain low confidence.
Use native MediaWiki link, search and rename components. Full search-link demonstrative phrasing and board genitive wording remain low confidence and need fluent review. Preserve the search-link purpose and board target.
Use the native plural member noun while preserving board membership scope. The complete all-board-members compound and kanban board terminology remain low confidence for fluent review.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Apply Markdown, emojis and permitted HTML to card and sidebar activity values. Sanitize completed sentences and honor plain-link mode, retaining existing source URL guards and avoiding nested navigation anchors. Add positive, negative and browser regression coverage.
Thanks to xet7 !
Remove an extraneous first qualifier and use native edit/text components. Full as-text phrasing and bound spelling remain low confidence; candidate checklist control vocabulary is marked Kabyle and is not established as Moroccan usage.
Thanks to xet7 !
Replace French and Arabic using native component terms. Full description-with-more-details composition remains low confidence; all-users view usage also needs fluent review.
Thanks to xet7 !
Preserve no-date and calendar-week scope using reference-supported components. Full deadline wording, next-week agreement and bound-state morphology remain low confidence for fluent review.
Thanks to xet7 !
Use CLDR today/tomorrow terms and reference-supported date components. Complete due-date terminology adaptation remains low confidence for fluent review; preserve the distinction from completed cards.
Thanks to xet7 !
Replace Arabic and French with profile-picture controls. Native component terms and confirmation frame support the repairs; full compounds, bound state and demonstrative placement remain low confidence for fluent review.
Thanks to xet7 !
Replace French while preserving cards-or-lists scope and the current-time qualifier. Native component terms support the repairs; composed phrases and kanban card morphology remain low confidence for fluent review.
Thanks to xet7 !
Replace three French labels using native filter, title and list component terms. Preserve command and heading distinctions. Full title-filter phrases, card bound state and filter noun morphology remain low confidence for fluent review.
Thanks to xet7 !
Apply membership-only scope to search selectors and pagination while retaining public discovery for other callers. Add regression coverage for shared access and public boards.
Thanks to xet7 !
Record dated source commit c6ee67cb1, four repaired original findings, filename refinement, 17313 correction records and 718 pending originals. Preserve explicit linguistic caveats and the full remaining validation scope. Audit and changelog checks pass.
Thanks to xet7 !
Replace four French add/remove-label activity messages with native tag and directional terminology, preserving label/card placeholder roles. Active addition inflection, default actor form and complete activity clauses remain low confidence pending fluent review. Refine the existing filename correction with directly attested upload-form wording and preserve its original before value. All 17313 correction/rendering checks pass.
Thanks to xet7 !
Record source commit 1d4ad977d dated 2026-09-14, six repairs including three unflagged values, 17309 correction records and 722 pending originals. Preserve full language-validation scope and explicit low-confidence terminology caveats. Audit and changelog checks pass.
Thanks to xet7 !
Replace Arabic label/create-label/no-results text and French username/label/color lookup errors with native terminology and reference-supported clauses. Preserve all percent placeholders and distinguish missing username, named label and label color. Composed errors, create-label usage and color/tag morphology remain low confidence pending fluent review. All 17309 correction/rendering checks pass.
Thanks to xet7 !
Record dated source commit e335ef034, 17303 correction records, 15119 resolved originals and 725 pending originals. Distinguish two unflagged label repairs and retain low-confidence credential composition and the broader validation scope. Correct the current largest-queue summary and update Upcoming.
Thanks to xet7 !
Replace French password confirmation and forgotten-password labels with native MediaWiki wording. Compose the username/password-required error from attested obligation and credential terms; the complete composition is low confidence pending fluent review. Preserve existing correct translations, key order and placeholders. All 17303 correction/rendering checks pass.
Thanks to xet7 !
Update Upcoming and title rendering documentation with cumulative-flow and Control chart security policies. Record authenticated legacy avatar prefix fallback, passed focused checks, unrun live browser tests and the unresolved production attachment 404. Keep translation audit counts unchanged.
Thanks to xet7 !
Explicitly verify cumulative-flow and Control chart wrappers use the shared viewer. Add completed-card browser fixtures for Control chart and check report headings and card titles with formatted, plain-link and literal-source policies.
Thanks to xet7 !
Render chart headings and report table headers and cells through the shared security-aware viewer. Use rendered text and emoji for canvas labels and dataset titles, capturing them before afterFlush so policy changes remain reactive. Extend title adapter, chart context and cumulative-flow browser policy coverage.
Thanks to xet7 !
The early universal file handler returned 404 for CollectionFS avatars before the legacy fallback handler could run, including versioned Meteor-Files URLs. Read legacy avatar metadata and streams only after authenticating the request, retain safe response headers, close conditional-request streams and preserve missing-file responses. Add positive and negative runtime coverage and a browser image regression.
Thanks to xet7 !
Record shared viewer behavior for timeline and Gantt task titles, both Admin Panel plain-text policies, SVG label limitations and the remaining live browser verification.
Thanks to xet7 !
Render remaining board titles through the shared Markdown and emoji viewer, including DHTMLX task names. Escape rendered text in Frappe SVG labels and use formatted titles in chart popups. Observe settings when charts refresh. Import routing and date dependencies explicitly in the assignee view to prevent ReferenceErrors. Add runtime helper, compiler and browser regression coverage.
Thanks to xet7 !
Use the native create-account command and compose the not-created user error from attested wording. Keep the complete error sentence explicitly low confidence pending fluent review.
Thanks to xet7 !
Verify the shared viewer passes the existing renderLinksAsPlainText setting to the sanitizer. Register browser tests retaining Markdown and emojis while changing link clickability; restore global settings after each test.
Thanks to xet7 !
Replace Arabic labels with native text and number terminology. Keep the numeric noun adaptation explicitly low confidence for fluent review.
Thanks to xet7 !
Reuse the shared Markdown and emoji viewer, including Admin Panel plain-text security mode. Keep overtime status outside user-authored Markdown. Add normal and plain-text browser regressions.
Thanks to xet7 !
Use the CLDR Persian language name and compose the Excel card-export command from attested terms, preserving the existing card noun. Record low confidence for the complete export phrase.
Thanks to xet7 !
Compose native user-exists and user-does-not-exist labels from attested MediaWiki nouns and existence forms. Keep both full sentences explicitly low confidence pending fluent validation; preserve their opposite meanings.
Thanks to xet7 !
Replace thirteen French and Arabic interface values using matching native MediaWiki terminology. Preserve existing valid Tamazight alternatives and record exact before/after values.
Thanks to xet7 !
Replace the rejected legacy isRTL option in single-board and multi-board calendars. Verify both directions and absence of the old option; add browser coverage for rendered direction and console warnings.
Thanks to xet7 !
Record the dated translation commit, passing correction checks and 732 pending original findings. Preserve wider language-validation caveats.
Thanks to xet7 !
Replace the French label with the exact native MediaWiki invalid-email-address message. Existing correction regressions verify rendering, placeholders and preference for newer correct translations.
Thanks to xet7 !
Native MediaWiki messages attest shared database and file terminology. Keep the complete raw-file label pending until its remaining wording is validated. Correct the stale Tamazight TODO count to 590.
Thanks to xet7 !
Record 15,111 corrected originals, 733 pending and 17,277 correction records. Preserve unconfirmed reference and fluent-review caveats. Audit/changelog suites pass.
Use CLDR Greenlandic persiskisut while preserving Jalali proper name. Record unconfirmed reference status and remaining fluent technical review. All 17,277 correction/rendering checks pass.
Record dated terminology review without changing repair counts. Three Manx originals and broader linguistic validation remain open. Correction and audit/changelog tests pass.
Current CLDR supplies no calendar display names. Keep pending Coptic and full tabular/epoch terminology open, including fluent review of composed sighting wording. No values or counts changed. All correction checks pass.
Use dictionary-attested crimson adjective sani with native spelling sañi. Record polysemy and unresolved exact dialect/hue validation. Preserve distinct red/purple labels. All 17,276 correction/rendering checks pass.
Record dated repair, 17,275 correction records and thirteen remaining palette wrappers. Original pending count remains 734; broader linguistic validation stays open. Audit/changelog suites pass.
Use directly attested sky-blue adjective qhusi instead of English in unrelated message wrapper. Keep blue and pale-turquoise variants distinct. All 17,275 correction/rendering checks pass.
Use directly attested orange-colored adjective killmu instead of English wrapped in unrelated message wording. Preserve distinction from yellow. All 17,274 correction/rendering checks pass.
Record dated provisional naming and missing technical variant terms without changing counts or claiming completed repairs. Correction and audit/changelog checks pass.
Review current CLDR calendar names and identify absent Buddhist and Hijri variant terminology. Keep existing values pending technical and fluent review; no translation values or counts changed. All 17,273 correction checks pass.
Compose native preference and user terminology; retain explicit low-confidence grammar and UI terminology review. All 17,272 correction/rendering checks pass.
Replace French with native change and username terminology matching the English source. Full composed label remains low confidence. All 17,271 correction/rendering checks pass.
Compose native delete command and comment noun with question marking. Full prompt grammar remains low confidence and requires fluent review. All 17,270 correction/rendering checks pass.
Update dated audit and changelog with four unflagged repairs and 17,269 correction records. Original pending count remains 737. Report regressions pass; broader validation remains open.
Replace four Arabic labels with matching native UI terms. All 17,269 correction/rendering checks pass, preserving correct translations and placeholders. Broader linguistic validation remains open.
Update dated audit and changelog with eleven unflagged repairs and 17,265 exact correction records. Original pending count stays 737. Audit and changelog regression suites pass; broader validation remains open.
Record dated repair commit and 17,254 exact corrections. Original pending count remains 737; wider language validation stays open. Audit and changelog regression suites pass.
Replace twelve Arabic labels with matching native UI terminology, including distinct Date and History nouns and login/logout commands. Preserve correct translations. Correction and rendering regressions pass; broader linguistic validation remains open.
Use exact native MediaWiki equivalents for Actions, Create, Download and Error. All 17,242 correction/rendering checks pass; existing correct translations and placeholders are preserved. Wider linguistic review remains open.
Record two repairs outside the original finding inventory and unchanged 737 pending originals. Correction/rendering and audit/changelog regressions pass; broader linguistic review stays open.
Use matching native MediaWiki UI terms. Preserve valid Latin-script labels and newer translations. All 17,238 correction and rendering checks pass. Broader language validation remains unfinished.
Record dated reference review and unresolved full calendar qualifiers without changing repair counts or claiming linguistic completion. Correction inventory and all three audit/changelog regression suites pass.
Keep existing wording during reference review. Unicode CLDR marks Islamic and civil labels provisional and supplies neither Saudi sighting nor astronomical tabular variant names. Full qualifiers require further Kashmiri technical terminology research. All 17,236 correction checks pass; no translation values changed.
Use exact native-script Unicode locale names for Saudi sighting and tabular variants. Verify variant distinctions and all 17,236 correction records. Keep compact epoch wording and broader linguistic validation open.
Replace English gold and silver wrapped in unrelated prose with composed material-color wording. Record composition and palette adaptation as low confidence for technical review. All 17,234 correction checks pass.
Use attested color adjectives and preserve their distinction from blue. Keep silver metal-to-color adaptation and wider palette validation unresolved. All 17,232 correction checks pass.
Use dictionary-attested standalone adjectives and verify six distinct repaired basic colors. Preserve unresolved orange and shade terminology for further research. All 17,230 correction records pass.
Replace English color names wrapped in unrelated prose with dictionary-attested standalone adjectives. Verify distinct colors and all 17,227 exact correction records. Original calendar findings and wider validation remain open.
Preserve all-notifications scope using existing terminology and reference-supported delete and all words. Track composed regional and technical wording as low confidence. All 17,224 exact correction checks pass.
Replace seven Arabic and French labels with matching Standard Moroccan Tamazight reference wording. Verify native script, distinct login and logout, and all 17,223 exact correction records. Preserve correct local translations and keep wider validation open.
Use lulachi, explicitly attested as indigo in the publisher linguistic paper. Preserve lowercase color labeling and distinguish blue. Magenta and broader dialect and technical wording validation remain open. All 17,216 correction checks pass.
Use reference-attested Jewish terminology with the existing calendar construction. Record the composed name as low confidence pending fluent technical review. All 17,215 exact correction checks pass.
Preserve Saudi Arabia and moon-observation qualifiers using native reference terms. Record low-confidence phrase composition and crescent-sighting adaptation for further review. Verify all 17,214 correction records and calendar variant distinctions.
Use native-reference astronomy wording and existing table/CLDR calendar-era terms, preserving both qualifiers and distinction from civil. Correction/rendering checks pass. Low confidence: noun composition and era-to-epoch adaptation need fluent technical review.
Thanks to xet7.
Replace English with reference-based calendar, table, civil and era wording. Preserve both qualifiers and the existing base. Correction/rendering checks pass. Low confidence: phrase composition and the era-to-epoch adaptation need fluent technical review. Other two variants remain unresolved.
Thanks to xet7.
Refine the existing provisional repair using the lexicon epoch term and CLDR astronomical adjective. Preserve original correction provenance and distinguish calendar variants. All correction/rendering checks pass. Low confidence: the calendar base is CLDR-unconfirmed and phrase composition needs fluent technical review.
Thanks to xet7.
Use the exact provisional non-core CLDR display name and retain distinctions from civil and sighting variants. Correction/rendering checks pass. Low confidence: the CLDR value is unconfirmed and an explicit astronomical-epoch qualifier still needs language research and fluent review.
Thanks to xet7.
Confirm the transitive increase/decrease commands from Veps inflection tables and distinguish intransitive forms. Preserve technical usage review and unresolved keyboard findings. All correction/rendering checks pass; counts are unchanged.
Thanks to xet7.
Replace two Finnish values with dictionary-based scale terminology and existing Veps prompt wording. Preserve the exact 50-300% range. Correction/rendering and placeholder checks pass. Low confidence: screen-zoom adaptation of the map-scale term and prompt inflection need fluent technical review.
Thanks to xet7.
Replace two unflagged Finnish labels with distinct dictionary-based increase and decrease actions. Preserve zoom behavior and limits. Exact correction/rendering and token checks pass. Low confidence: technical usage and imperative forms need fluent review.
Thanks to xet7.
Update dated translation progress to 15,095 corrected and 749 pending original findings. Record 17,205 verified correction records and the pending live browser and fluent-language checks. Thanks to xet7.
Fetch missing parent issues and pull metadata through the existing rate-limited API client. Preserve page checkpoints on failure and retry missing pull metadata after interruption. Report logs after menu sync/check operations and command exit while retaining exit status. Offline collector, menu and shell launcher regressions pass.
Thanks to xet7.
Replace Finnish search explanations and the overdue keyword, preserving placeholders, examples and day bounds. Fix Query to use the translated overdue predicate map while retaining its existing English alias. Actual parser and all correction regressions pass. Add and syntax-check a browser regression; isolated live browser execution remains pending. Composed operator/date-bound language needs fluent review.
Thanks to xet7.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Replace four Finnish labels, preserving per-swimlane and ensure-if-missing scope and distinguishing lost cards from restored items. Production rendering and all correction checks pass. Expanded ensure clauses and case agreement have low confidence and need fluent review.
Thanks to xet7.
Refresh dated audit evidence and upcoming changelog with verified explanations, remaining findings and explicit language-review limitations.
Thanks to xet7.
Replace four Finnish explanations, preserving one-time scope, continued board use, performance improvement, brief duration and background continuation after browser closure. Production rendering and all correction checks pass. Technical performance/structure clause composition has low confidence and needs fluent review.
Thanks to xet7.
Update dated audit evidence and upcoming changelog with verified safety conditions, remaining findings and language-review limitations.
Thanks to xet7.
Replace three Finnish warnings, preserving empty-list and populated-same-name-duplicate conditions, initial shared-list conversion and redundant-only deletion. Read the migration implementation and verify production rendering and all correction invariants. Composed clauses and case agreement have low confidence and need fluent review.
Thanks to xet7.
Replace six Finnish migration/settings values, preserving list ordering, card positions, swimlane structure, independent execution and brief duration. Production rendering and all correction checks pass; composed purpose clauses and case agreement need fluent review.
Thanks to xet7.
Refresh the dated audit and upcoming changelog with verified migration labels, remaining findings and explicit language-review limitations.
Thanks to xet7.
Replace five Finnish values, preserving comprehensive migration scope, analysis, missing/corrupt list alternatives and continuation confirmation. Production rendering and all correction checks pass. Technical structure terminology and absent-list clause composition have low confidence and need fluent review.
Thanks to xet7.
Replace nine Finnish wait-animation labels while preserving all animation distinctions and identifiers. Production rendering and all correction checks pass. The technical cube loan and composed wait-indicator terminology have low confidence and require fluent review.
Thanks to xet7.
Refresh the dated audit and upcoming changelog. Condense review categories while retaining all per-key confidence caveats in the correction ledger and source commits.
Thanks to xet7.
Replace Finnish spent-time values, retaining the distinction between boards with tracked-time cards and the hours field. Production rendering and all correction checks pass. The composed tracked-time-card phrase has low confidence and needs fluent review.
Thanks to xet7.
Replace four Finnish values while preserving distinct mobile/desktop modes and the alternative download action. Production rendering and all correction checks pass. Mobile-device compounds and PDF-preview inflection have low confidence and need fluent review.
Thanks to xet7.
Replace ten Finnish values, preserving system-wide and administrator announcement distinctions, create/upload/update/sign-in actions and the existing repository noun. All correction and production-rendering checks pass. Repository inflection and the system-wide qualifier have low confidence and need fluent review.
Thanks to xet7.
Update the upcoming changelog and audit progress with saved alert findings, twenty-five passing mirror regressions and native Windows/CodeQL verification limits.
Thanks to xet7.
Review saved scanning alerts 537 and 539. Make exact archive-host validation explicit, restrict executable dispatch and run Windows targets through the existing Node engine without cmd.exe command strings. Preserve preview flags and all archive/resume behavior. Twenty-five focused mirror test entries pass; native Windows and remote CodeQL rescanning remain unverified.
Thanks to xet7.
Update the dated audit and upcoming changelog with verified repairs, the earlier pronoun correction and remaining language-validation work.
Thanks to xet7.
Replace the Finnish timing label and refine an earlier shortcut correction from assigned to you to assigned to me. Preserve the original before-value in the correction ledger. Production rendering and all correction checks pass; timing participle composition needs fluent review.
Thanks to xet7.
Replace eight Finnish/Venda instructions, preserving click, drag, drop, resize, opening and closing distinctions and workspace placeholders. All correction and production-rendering checks pass. Icon inflection and desktop drag-handle compounds have low confidence and need fluent review.
Thanks to xet7.
Update the dated audit and upcoming changelog with the verified workspace batch, remaining findings and explicit language-review limitations.
Thanks to xet7.
Replace thirteen Finnish values, preserving workspace/subworkspace distinctions, markdown notation and the existing Veps deletion question. Verify production rendering and all correction invariants. Composed subworkspace and technical icon terminology have low confidence and need fluent review.
Thanks to xet7.
Replace nine Finnish values, preserving board/list destinations, matching-card absence, deletion confirmation and the board placeholder. Verify actual rendering and retain the existing subtask heading. Composed destination and matching-card grammar need fluent review.
Thanks to xet7 !
Replace Finnish prose using attested naming vocabulary and existing card/list/swimlane/board location phrases. Verify actual rendering with all five placeholders. Mention adaptation and composed notification grammar have low confidence and need fluent review.
Thanks to xet7 !
Translate empty-field matching and starring a board to add its navigation link. Verify actual rendering and preserve tokens and existing star hint. Composed wildcard grammar and navigation-bar terminology need fluent review.
Thanks to xet7 !
Use Unicode CLDR Ewe islamic-civil terminology and verify actual locale rendering, preserving source tokens. CLDR marks the name provisional; native validation remains required.
Thanks to xet7 !
Use Unicode CLDR Persian language names and existing calendar nouns while preserving Jalali identity and distinction from Hijri. Verify actual locale rendering and token inventories. Technical calendar-name composition needs native review.
Thanks to xet7 !
Replace four Finnish values in label and member action popups. Preserve existing correct assignment and label-removal wording and verify rendering. Composed title grammar needs fluent review; apparent reversed member handlers remain a separate review item.
Thanks to xet7 !
Use dictionary-attested alimento, keeping all three comma-separated entries and numeric suffixes. Verify production rendering and token preservation. Technical checklist use needs native review.
Thanks to xet7 !
Replace nine Finnish or Venda labels, preserving single versus multiple-board calendars, existing list and time terminology and Gantt proper names. Verify production rendering. Composed view-name grammar and collapse terminology have low confidence and require fluent review.
Thanks to xet7 !
Replace five Finnish values while retaining avatar storage, writable and base-directory paths, and upload-or-rename cancellation. Verify production rendering and preserve existing attachment-path wording. Base-folder terminology and cancellation grammar have low confidence and require fluent review.
Thanks to xet7 !
Replace four Finnish values while retaining unread filtering, read/unread marking and read-only deletion. Preserve the existing correct unread-comment phrase and verify production rendering. Unread participle inflection and composed notification grammar have low confidence and need fluent review.
Thanks to xet7 !
Replace Finnish labels with Veps and distinguish resident RAM, allocated heap, actual heap use and external memory. Verify production rendering and preserve all source tokens. Composed technical grammar has low confidence and needs fluent review.
Thanks to xet7 !
Record successful Meteor compilation, Node regressions and Chromium/Firefox verification against an empty database. Changelog checks pass.
Thanks to xet7.
Override Meteor's native CSS module type for the existing style-loader/css-loader pipeline. Initialize the second-factor form with a literal native hidden attribute and toggle it only on the existing challenge/cancel paths.
Meteor bundle compilation, four Node test entries and Chromium/Firefox checks pass against an isolated database with zero users. Signed-out sign-in and sign-up remain styled without an unsolicited challenge, even if its hide class is removed.
Thanks to xet7.
Update Audit.md and TODO Later with 803 pending original findings, exact repair counts and low-confidence warning terminology. Metadata checks pass.
Thanks to xet7.
Refresh Audit.md and TODO Later with exact correction totals, 806 pending original findings and uncertain confirmation grammar. Changelog and audit metadata checks pass.
Thanks to xet7.
Preserve ANY condition for repeated operators versus ALL conditions for differing operators. Dictionary-supported Veps prose and sample values replace Finnish; composed logical grammar remains low confidence.
Actual parser grouping and all 17,070 correction regressions pass.
Thanks to xet7.
Translate ten Finnish values with single-word parser keywords and a working negative due-date example. Preserve all field placeholders and presence/absence meanings. Composed instructional grammar is low confidence and requires fluent review.
Actual Query presence/absence checks and invalid-field rejection pass, alongside all 17,068 correction regressions.
Thanks to xet7.
Refresh Audit.md and TODO Later with 817 pending original findings, exact correction totals and low-confidence grammar requiring review. Changelog and audit metadata checks pass.
Thanks to xet7.
Replace sixteen Finnish values, preserving scheduling failures versus operation failures, successful scheduling and coming-soon functionality. Reuse existing job and backup terminology with dictionary-supported cleanup wording.
Composed scheduling syntax and backup/archive inflection are low confidence and require fluent review. All 17,058 correction records pass runtime rendering, placeholders, key order and human-preference regressions.
Thanks to xet7.
Record dated Veps heap repairs, 829 remaining original findings and low-confidence terminology. Refresh TODO Later counts and distinguish historical full-suite verification from current correction checks.
Thanks to xet7.
Replace eleven Finnish memory labels with Veps terminology; distinguish peak malloc allocation from erroneous memory and the V8 debug overwrite flag from garbage collection. Preserve metric distinctions and identifiers.
Technical compounds and inflection are low confidence and require fluent review. Runtime rendering, token, key-order and human-preference regressions pass for 17,042 correction records.
Thanks to xet7.
Document completion log paths, read-only manifest repair and successful Linux arm64 builds with release startup validation. Keep translation audit status unchanged. Changelog and audit metadata checks pass.
Thanks to xet7.
Print development and release log paths at completion on shell and Windows builds. Match the release workflow by making Meteor's server package manifest writable before updating node-gyp and installing dependencies.
Add completion/failure and read-only-manifest regressions. Development compilation and release startup smoke check pass on Linux arm64; 13 targeted test entries pass. Native Windows execution is unavailable.
Thanks to xet7.
Replace eight Finnish values, resolving six original findings and two unflagged watch labels. Preserve combined consent text, never-notified state, creator OR member and watch subscriptions. Runtime checks pass. Legal argument case and composed technical grammar remain low confidence pending fluent review.
Replace eight Finnish values, resolving five original findings and three unflagged errors. Preserve color-or-name matching, positive per-page limits, status choices and descending minus syntax. Localize user shorthand and fix unmatched label emphasis. Production Query and renderer checks pass; composed grammar remains low confidence pending fluent review.
Replace twelve Finnish values, resolving four original findings and eight unflagged errors. Preserve date bounds, signed integers, period placeholders and case-insensitivity wording. Production Query verifies localized date-sort predicates and invalid date operands; runtime checks preserve period interpolation. Technical grammar remains low confidence pending fluent review.
Replace seven Finnish values, resolving five original findings and two unflagged action labels. Preserve board title interpolation, removal from every board card, duplication and insufficient available disk space. Runtime and positive/negative wording checks pass. Technical morphology remains low confidence pending fluent review.
Replace six Finnish values, resolving five original findings and one unflagged owner label. Preserve four distinct people roles, three board-location fields, one checklist item per text line and original order. Runtime checks pass; composed technical morphology remains low confidence pending fluent review.
Replace nine originally flagged Finnish values. Preserve literal JSON fields and first/second/last examples, minicard placement, checklist template source, settings prohibition and at least one administrator. Runtime and JSON regression checks pass. Composed technical morphology remains low confidence pending fluent review.
Replace eight Finnish values, resolving six original findings and two unflagged errors. Preserve placeholders and separate number, sorting, status, existence, debug and limit meanings. Verify runtime rendering and positive/negative production Query limit behavior. Technical morphology remains low confidence pending fluent review.
Replace ten Finnish values, resolving five original findings and five unflagged errors. Preserve member OR assignee, creator distinction, end-date status and default archive exclusion. Verify localized terms through production Query and runtime rendering. Composed technical grammar remains low confidence pending fluent review.
Replace eleven Finnish or mixed-language values, resolving six original findings and five unflagged errors. Preserve all placeholders and test five localized operators through production Query with quoted values. Use a single-word assignee operator because the parser rejects spaces. Technical case and relative-clause wording need fluent review.
Replace eleven Finnish values, resolving ten original findings and one unflagged value. Preserve assigned-time job meaning, deletion confirmation, active jobs, and delete/pause/resume/start success versus failure. Composed scheduling terminology and morphology need fluent-speaker review.
Replace ten Finnish values, including one original flagged warning. Preserve restore targets, validation and continued background processing with potentially longer completion. Composed technical grammar is low confidence pending fluent-speaker review.
Correct the npm-update stage to describe its application compilation for Meteor plugin dependencies. Enable verbose npm logging, foreground lifecycle scripts, Meteor timing diagnostics and supported verbose bundle compilation. Preserve unbuffered stdout/stderr and test command output plus supported options.
Thanks to xet7 !
Use existing Veps comment terminology for counts, minicards, unread/absent states, roles and search instructions. Preserve sprintf and interpolation tokens. Verify actual production Query parsing with the apostrophe-containing operator, quoted multiword values and unknown-operator rejection. Composed relative-clause/count/case grammar is low confidence and needs fluent-speaker review.
Thanks to xet7 !
Replace Finnish and Venda values with consistent Veps messages. Preserve administrator/member requirements, username-or-password errors, comma/Tab delimiters, self-invitation restrictions and domain ownership. Align the invitation-code label with existing registration emails. All exact correction and runtime checks pass. Composed import-schema, login-event, domain ownership and case grammar are low confidence and need fluent-speaker review.
Thanks to xet7 !
Replace Finnish warnings for cards, labels, board contents, accounts, comments, checklists, checklist items and subtasks. Preserve permanent deletion, history/activity loss and inability to restore or reopen. Verify positive targets and negative target distinctions with runtime translations. Composed board-content wording, account loan inflection and definite-object grammar are low confidence and need fluent-speaker review.
Thanks to xet7 !
Replace Finnish and Venda values with Veps private/public labels, permission descriptions and custom/default visibility controls. Preserve HTML, URLs and query token semantics; verify the production Query parser against the repaired locale. Composed visibility/search-engine wording and case grammar are low confidence and need fluent-speaker review.
Thanks to xet7 !
Stream stage announcements, elapsed status and exit codes into the build log. Stop after required cache cleanup or dependency installation failures. Verify quiet command progress and failure propagation with offline fixtures.
Thanks to xet7 !
Place the existing collapse control immediately after Home and before the page or board title. Preserve per-session collapse behavior and themed layout. Update header ordering guards and add desktop/narrow-layout browser coverage for position and retained Home/title visibility.
Five header suites pass. Browser regression syntax-checks and registers; runtime execution requires a running WeKan server, which is unavailable locally.
Thanks to xet7 !
Update dated fix hash, audit summary, TODO Later counts and Upcoming release notes. Three original findings and ten related errors repaired; 963 original findings remain.
Thanks to xet7 !
Update dated fix hash, audit summary, TODO Later counts and Upcoming release notes. Seven original findings and two related errors repaired; 966 original findings remain.
Thanks to xet7 !
Update dated fix hash, audit summary, TODO Later counts and Upcoming release notes. Eleven original findings and one related error repaired; 973 original findings remain.
Thanks to xet7 !
Replace twelve Finnish values. Preserve later recovery, retained activity, all archived versus non-archived lost-item scope, exact identifier names, automatic repair and cannot-easily-undo wording. Add actual rendering and negative scope regressions.
Low confidence: composed recovery grammar and plural/case forms require fluent-speaker review.
Thanks to xet7 !
Update dated fix hash, audit summary, TODO Later counts and Upcoming release notes. Five original findings and six related errors repaired; 984 original findings remain.
Thanks to xet7 !
Replace eleven Finnish values, including related shortcut actions and unflagged labels. Preserve optional authentication, outbound/two-way/global semantics, disabling versus deletion, organization/team guidance and personal versus assigned-card filtering.
Low confidence: composed Veps labels and contact guidance need fluent-speaker review.
Thanks to xet7 !
Update dated fix hash, audit summary, TODO Later counts and Upcoming release notes. Four original findings resolved; 989 remain alongside restored and unflagged validation.
Thanks to xet7 !
Replace four Finnish values and verify the literal Enter key, worker-only move/self-assignment/comment permissions, unsaved description state and irreversible loss of all swimlane actions.
Low confidence: composed Veps grammar and inflections require fluent-speaker review.
Thanks to xet7 !
Update dated fix hash, audit and TODO Later counts, and Upcoming release summary. Six original findings resolved; 993 remain, alongside restored and unflagged validation.
Thanks to xet7 !
Replace six Finnish values, preserve creator-or-member and board notification scope, signed-in-only support, archive location and swimlane name formatting. Verify actual locale rendering and negative scope checks.
Low confidence: composed Veps grammar and inflections need fluent-speaker review.
Thanks to xet7 !
Update dated source hash and maintained totals to 14,745 corrected, 1,099 pending and 16,535 exact records, with 358 Veps findings remaining. Record mapping and shortcut semantics, passing checks and outstanding broader language validation.
Thanks to xet7 !
Replace 25 Finnish import, invitation, account-state, autocomplete and navigation values. Preserve ZIP attachment directories, CSV/TSV separators, existing-user mapping and the unmapped-member current-user fallback. Correct the assignee shortcut to add/remove assignment while retaining 1-9 and board-addition order. Keep conditional import-error guidance and match WeKan navigation labels while preserving Trello interface literals.
All exact correction records and actual positive/negative rendering checks pass. Composed technical UI wording has low-confidence inflection and needs fluent-speaker review.
Thanks to xet7 !
Update the dated source commit and maintained totals to 14,723 corrected, 1,121 pending and 16,510 exact records, with 380 Veps findings remaining. Record passive-form refinements, permission fidelity and passing rendering checks; retain broader language validation work.
Thanks to xet7 !
Repair/refine 43 role, member, assignee, selection and related UI values: 26 new records and 17 refinements. Preserve read/comment/normal permissions and assigned-only current-user visibility, board/card scopes, add versus assign, all-card removal plus notification and numeric selection ranges. Replace every malformed märitadud occurrence with the reference-confirmed märitud while retaining original before records.
All correction records and actual positive/negative placeholder rendering checks pass. Composed role and UI phrasing has low confidence and needs fluent-speaker review.
Thanks to xet7 !
Update the dated source hash and maintained summaries to 14,705 corrected, 1,139 pending and 16,484 exact records, with 398 Veps findings remaining. Document item-stem refinements and passing actual rendering checks without claiming broader language validation is finished.
Thanks to xet7 !
Repair/refine 39 list/card/custom-field/checklist/archive controls: 36 new records and three item-stem refinements preserving original before values. Keep top/bottom and current/selected-list rules distinct, retain checked/all/completed meanings and preserve archive recovery, activity history and irreversible deletion warnings. Match navigation instructions to translated menu/archive headings.
All correction records and positive/negative actual rendering checks pass. Composed kanban wording and UI inflections have low confidence and need fluent-speaker review.
Thanks to xet7 !
Update the dated source hash, summary and TODO Later to 14,675 corrected, 1,169 pending and 16,448 exact records. Keep 428 Veps findings and broader restored/unflagged and fluent-speaker reviews explicit.
Thanks to xet7 !
Replace Finnish/Venda filters, countdowns, export date fields, sorting and due-card view text. Repair received-date wording that used the word for a statement and the malformed past deadline adjective. Retain correct Minä. Preserve this/next week, tomorrow, countdown arguments, five export date types and incomplete-card/board-permission conditions.
Actual locale rendering, positive/negative semantics and all correction records pass. Composed UI inflections have low confidence and need fluent-speaker review.
Thanks to xet7 !
Correct the remaining Veps count and latest translation source hash. Distinguish the passing 1,015-suite Node run from the later passing date correction/rendering checks.
Thanks to xet7 !
Record the dated repair commit and passing correction/rendering checks. Update current totals to 14,670 corrected, 1,174 pending and 16,427 exact records, with 433 Veps findings remaining. Preserve the outstanding restored/unflagged and fluent-speaker reviews.
Thanks to xet7 !
Replace 39 Finnish or mixed Finnish/Venda date controls, rule labels, date activities and reminders with Veps reference vocabulary. Preserve received/start/due/end distinctions, set-or-change rule semantics, old/new time values, exact placeholders and approaching/current/overdue reminder states. Test actual i18next underscore and sprintf argument rendering with negative wrong-language checks.
Composed date and reminder phrasing has low-confidence inflection and needs fluent-speaker review.
Thanks to xet7 !
Link the committed toolchain upgrade from Upcoming, record Docker and lockfile consistency and passing Node checks, and retain the pending full Meteor bundle verification. Update the translation audit interruption summary without changing repair counts.
Thanks to xet7 !
Commit Meteor 3.6-beta.0 release and package pins, the matching Docker Meteor metadata, @meteorjs/rspack 3.0.0-beta.1, Rspack CLI/core/dev-server 2.2 and the explicit SWC compiler. Update the npm lockfile consistently with the development dependencies and pin existing account packages.
All 1,015 Node suites and the parser compilation and version consistency regressions pass. Full Meteor bundle verification remains pending at local tool startup.
Thanks to xet7 !
Update the dated translation source hash and 16,388 correction record total. Keep the 1,193 pending original findings and 452 Veps findings unchanged because this batch repaired unflagged values. Record passing targeted checks and low-confidence wording review.
Thanks to xet7 !
Replace Finnish activity labels with native Veps action and notification vocabulary. Preserve exact before/after records and exercise actual locale rendering with a negative Finnish regression. The composed notification label has low-confidence inflection and needs fluent-speaker review.
Thanks to xet7 !
Document the parser source commit, seven runtime/build regressions and 1,015 passing Node suites. Preserve pending full Meteor bundle verification and translation repair counts. Record the latest maintainer-run upload report with 237 successes, five unsupported codes and an informational catalogue list.
Thanks to xet7 !
Remove the undeclared body-parser import while preserving JSON and URL-encoded parsing, the 50MB limit and simple form decoding. Exercise real HTTP requests, malformed and oversized JSON, compression and Rspack compilation. Permit the canonical Meteor prerelease in the website manifest regression while rejecting stale Docker metadata.
Thanks to xet7 !
Update dated Audit and Upcoming with source commit, attested added participle refinements, 14,651 corrected findings, 1,193 pending and 16,386 exact correction records. Refresh TODO Later and retain remaining translation review status.
Thanks to xet7 !
Repair thirty-two values: twenty-three new correction records and nine refinements preserving original before values. Resolve sixteen original findings. Translate checklist/custom-field/comment activities and rule triggers, correcting all ližadud occurrences to dictionary/inflection-table and native MediaWiki ližatud. Preserve checkbox versus completion, reopening, add/remove context and field clearing versus deletion. Exact correction, underscore and sprintf argument-order regressions pass. Low confidence: composed kanban terminology and remaining UI inflections need fluent review.
Thanks to xet7 !
Update dated Audit and Upcoming with the source commit, verified literal placeholders/entities, 14,635 corrected original findings, 1,209 pending and 16,363 exact correction records. Refresh TODO Later and retain outstanding fluent/restored-value review status.
Thanks to xet7 !
Replace twenty-three Finnish/Venda values with dictionary-backed Veps, resolving ten original findings. Preserve field types, multi-select, value/activity contexts and all-card irreversible deletion with history loss. Restore literal %{value}, preserve HTML space entities, and make generic/custom-field date labels consistent. Exact corrections, actual i18next interpolation, source tokens, entities and key order pass. Low confidence: composed custom-field/control terminology and UI inflections need fluent review.
Thanks to xet7 !
Update the dated audit and source commit, Upcoming summary and TODO Later counts: 14,625 corrected findings, 1,219 pending and 16,340 exact correction records. Record passing targeted checks and remaining fluent/restored-value reviews.
Thanks to xet7 !
Replace twenty-one Finnish, Venda and mixed values using dictionary and native MediaWiki evidence, resolving ten original findings. Preserve add/remove, check/uncheck, completion/reopening, subtask and board context, exact __checkList__ case, and (0/0) counters. Exact corrections, actual i18next interpolation, tokens and key order pass. Low confidence: composed kanban checklist/subtask terminology and UI inflection require fluent review.
Thanks to xet7 !
Update dated Audit and Upcoming with the source commit, thirty-two repairs, passing interpolation and correction regressions, 14,615 corrected findings, 1,229 pending and 16,319 correction records. Refresh TODO Later and preserve outstanding fluent/restored-value review status.
Thanks to xet7 !
Repair thirty-two values with dictionary-backed Veps, resolving twenty-two original findings. Preserve labels, attachments, comments, membership, archiving, imports, restoration and card move contexts/source destinations. Compose the swimlane metaphor from attested ujund and šoid and repair the unsupported seeded stem in deletion messages. Verify actual i18next rendering with production underscore interpolation, aliases, exact corrections, tokens and key order. Low confidence: kanban metaphors, compounds and UI inflections require fluent review.
Thanks to xet7 !
Update the dated audit, source commit, Upcoming entry and TODO Later counts: 14,593 corrected findings, 1,251 pending and 16,287 exact correction records. Record passing targeted checks and remaining fluent/restored-value reviews.
Thanks to xet7 !
Replace ten Finnish settings values with Veps using dictionary and native MediaWiki evidence. Preserve attachment batch counts, CPU percentage pause threshold, millisecond delay and all numeric ranges. Add actual i18next rendering and negative wrong-language/range regression checks. All 16,287 correction records verify. Low confidence: technical batch terminology, millisecond inflection and composed UI grammar require fluent review.
Thanks to xet7 !
Record the dated source commit, passing translation/rendering and changelog checks, 14,590 corrected findings, 1,254 pending and 16,277 exact correction records. Refresh stale TODO Later counts and identify the remaining Veps and Standard Moroccan Tamazight queues. Fluent and restored-value reviews remain outstanding.
Thanks to xet7 !
Replace fifteen Finnish values using Veps dictionary and native MediaWiki evidence. Preserve all-migration scope, pause versus stop, start versus resume, completion and failure outcomes. Use the existing migracii technical term rather than physical file transfer. Low confidence: loan inflection and composed UI grammar need fluent review. Exact corrections, actual i18next rendering, placeholders, JSON examples and key order pass regression checks.
Thanks to xet7 !
Update the dated audit, source commit and Upcoming summary: 14,583 corrected original findings, 1,261 pending and 16,262 exact correction records. Record remaining fluent-review work and passing regression checks.
Thanks to xet7 !
Replace 18 Finnish labels and descriptions, resolving seven original findings. Preserve protocol identifiers, secret credentials, literal region codes and storage distinctions; repair STMP to SMTP. Use reviewed dictionary and native MediaWiki terminology. Network loan words and composed authentication/UI grammar remain low confidence for fluent review. Exact token, key-order, ledger and actual i18next rendering regressions pass.
Thanks to xet7.
Link the implementation commit from Upcoming and record organization namespaces, static comment archives, enabled wiki/project handling and shared rate-limit behavior. Keep translation repair counts unchanged and record the mirror interruption outcome and remaining WebKit environment limitation.
Thanks to xet7.
Add organization management and per-destination namespaces to the shared Unix and Windows mirror menu. Discover all accessible repositories, create missing mirrors, retain PR conversations when issues are disabled, and copy enabled wiki history and portable Projects V2 data.
Archive linked media, files and webpage HTML per comment under host/organization/repository directories. Preserve old versions, generate static HTML and CSV catalogues, and support offline rebuilding from CSV. Attach archived files to corresponding destination comments where supported.
Honor GitHub and destination rate-limit headers, persistent cooldowns and bounded retries. Public GitHub REST reads fall back without a token. Add offline regressions and a static browser test; 1,014 Node suites pass, with final targeted checks passing. Chromium and Firefox static checks pass; local WebKit requires unavailable ICU 74.
Thanks to xet7.
Record the dated local source commit, twenty repairs and tested destination/deletion distinctions in the short audit summary and upcoming changelog. Update TODO Later to 14,574 corrected original findings, 1,270 pending and 16,233 correction records. Keep low-confidence language and restored-value reviews outstanding. Correction, audit-progress and changelog regressions pass.
Thanks to xet7 !
Replace twenty Finnish values with Veps backed by the Russian–Veps dictionary and native MediaWiki terminology. Preserve filesystem, MongoDB GridFS and S3 destinations, single-versus-all attachment scope, AWS/MinIO identifiers, save success/failure and permanent deletion with no undo. Use native Sirdä for moving files, distinct from navigation Sirte. Exact correction, placeholder, key-order and actual i18next rendering regressions pass. Low confidence: composed filesystem terminology, base-path compound päte, attachment participle and technical UI grammar need fluent review.
Thanks to xet7 !
Record the dated source commit and verified list-control repairs in the short translation audit and upcoming changelog. Update TODO Later to 14,555 corrected original findings, 1,289 pending and 16,213 exact correction records. Preserve the outstanding restored-value and fluent-language review scope. Correction, progress and changelog format regressions pass.
Thanks to xet7 !
Replace twelve Finnish list-control values with Veps vocabulary checked against the Russian–Veps dictionary and native MediaWiki translations. Preserve selected-list left/right positions and distinguish empty-only duplicate cleanup from all duplicate cleanup. Exact correction, placeholder, key-order and actual i18next rendering regressions pass. Low confidence: composed UI grammar and the derived plural genitive lugetišiden need fluent review.
Thanks to xet7 !
Keep commit hashes in link targets and show readable attachment and retry descriptions in the upcoming release. Changelog format regressions pass.
Thanks to xet7 !
Document the six-action saved mirror menu, selectable sources, native attachment links and archive retry behavior in the upcoming changelog. Record 1,011 passing Node suites and keep the translation audit summary current at 14,545 corrected findings, 1,299 pending findings and 16,201 correction records. Translation repairs are ready to continue after the mirror work.
Thanks to xet7 !
Preserve the existing launcher retry behavior: failed source inventory stops synchronization, but a local archive failure records an overall failure and still attempts supported data on every selected destination. Extend the injected-command regression to verify all targets run without live remote writes.
Thanks to xet7 !
Resolve relative GitLab, Codeberg and SourceForge attachment paths against the original forge in destination text and persistent archive discovery. Recognize current GitLab project upload URLs, preserve original JSON metadata and exclude arbitrary websites from downloads. Offline link and archive regressions pass.
Thanks to xet7 !
Default to GitHub as source and GitLab, Codeberg and SourceForge as mirrors. Share the six-action menu across Unix and Windows, save source and active destinations in .tools/mirror/settings.txt, and delegate synchronization to individual forge launchers. Support native source inventories and GitHub destinations, preserve original provenance and isolate source archives. Compare Git ancestry and inventory missing metadata without remote writes in check mode. Verify menu interaction, adapters, retries, settings validation and archive isolation with offline fixtures.
Thanks to xet7 !
Replace 27 Finnish activity and core labels using native Veps dictionary vocabulary. Preserve placeholder order and source/destination roles and verify real i18next sprintf rendering. Low confidence: composed kanban grammar, derived participles and list plural need fluent review.
Thanks to xet7 !
Refine the new Hijri labels from the complete dictionary: describe the epoch as aiganlugun augotiž, the origin of time reckoning, and use the genitive of kudmaine for moon observation. Correct the vocabulary provenance in the existing four repair records. Preserve distinct civil and astronomical variants and mark composed technical wording for fluent review.
Thanks to xet7 !
Replace English labels with Veps, retaining tabular civil and astronomical epoch distinctions and Saudi lunar observation. Use native vocabulary from the 2007 Zaiceva/Mullonen Russian-Veps dictionary and the Veps Saudi Arabia article. Record four exact repairs and add positive terminology and negative English/variant-collision regressions.
Low confidence: composed technical labels, the epoch-origin phrasing and adapted Coptic proper name need fluent Veps review.
Thanks to xet7 !
Record the 2026-09-13 source commit, native vocabulary evidence and low-confidence composed wording. Refresh original finding counts to 14529 corrected and 1315 pending, with 16170 exact corrections. Distinguish the latest targeted checks from the preceding full Node run.
Thanks to xet7 !
Replace Finnish username-length and self-addressed test-email strings using attested native Veps vocabulary. Preserve the inclusive minimum of three characters and the personal recipient. Also replace the Finnish text noun with native Veps Tekst. Record exact corrections and add vocabulary and minimum-boundary regressions.
Low confidence: composed username warning and test-email compound need fluent Veps review. Vocabulary source: https://raw.githubusercontent.com/wikimedia/mediawiki/master/languages/i18n/vep.json
Thanks to xet7 !
Document per-target mirror synchronization, persistent issue/pull/release file retention and the Veps export-title repair with source commit references. Refresh the translation correction count and latest local fix. Record 1010 passing Node suites and preserve the outstanding Chromium board-export and language review work.
Thanks to xet7 !
Keep complete source files under .tools/mirror/issues/<number>, pulls/<number> and releases/<version>. Persist metadata, comments, reviews, patches, GitHub-hosted attachments, binaries and source archives. Rename removed or changed versions with old-YYYY-MM-DD_HH-MM-SS prefixes; preserve existing copies on download failures and retry on later runs.
Archive once before per-target synchronization, reuse verified release files and guard concurrent archive writers. Preserve destination main commits through the existing merge fallback without force or ref deletion. Exclude disabled GitHub Discussions, projects and wiki. Document the design and verify retention, retries, API pagination and launcher behavior with offline fixtures.
Thanks to xet7 !
Replace an unflagged Zulu-seeded title with native Veps Ve, matching the repaired export command and MediaWiki export terminology. Record the exact correction and extend the chart-title regression. This resolves the remaining failure found by the full Node suite run.
Repair Tools menu dispatch and run separate GitLab, Codeberg and SourceForge launchers through a shared engine on Unix and Windows. Read one paginated GitHub snapshot for all mirrors, match issue/comment provenance and release tags, and retry missing conversations and binary assets after partial runs. Preserve destination text and copy Git branches/tags without force or deletions. SourceForge uses Tracker tickets and SFTP release files; projects and wiki are excluded. Add offline API, retry, pagination, multipart upload and launcher regressions plus setup/scope documentation.
Compose native user-image wording for avatar change/delete/upload states, allowed types and maximum sizes. Preserve the size placeholder, byte unit and deletion confirmation. Low confidence: composed avatar phrasing and byte-unit inflection require fluent review.
Thanks to xet7 !
Install Git, SSH/SCP/SFTP, curl, jq, Node and Go prerequisites with native Debian/Ubuntu, Fedora, Brew and Windows package mappings. Use native Go builds for missing forge CLIs, verified current Go archive bootstrap for older Unix toolchains, repository-local binaries and refreshed PATH. Report remaining missing tools and failure status without stopping later attempts. Add SourceForge to the Windows mirror targets. Offline Unix, PowerShell, architecture, checksum and menu regressions pass; no remote mirroring, uploads or publishing ran.
Thanks to xet7 !
Use native Veps software vocabulary for email addresses, send/sent/error states and active/inactive filters. Restore the plural address label, retain SMTP and preserve opposing states. Low confidence: composed SMTP test subject needs fluent review.
Thanks to xet7 !
Install Forge from cmd/forge instead of its library root and Tea from gitea.dev/tea instead of the obsolete code.gitea.io module. Apply paths on Unix and Windows. Report Unix Tea/Forge Go failures with nonzero status while continuing later tools. Offline regression covers Fedora detection, skips, paths and failure continuation; no packages or remote writes ran.
Thanks to xet7 !
Use native software vocabulary for ongoing uploads, failure, completion and upload limits. Preserve bytes and allowed file types. Low confidence: composed type and byte-unit inflections need fluent review.
Thanks to xet7 !
Use attested native Veps software commands, including rename. Preserve distinct import/export and close/delete actions with vocabulary and rejected seed regression coverage.
Thanks to xet7 !
Exercise all five unsupported language codes across failed registration, newly supported registration with full uploads, and subsequent uploads without duplicate additions. Document fresh project discovery, no persisted failure skip list, and mapping changes when catalogue codes differ.
Thanks to xet7 !
Use native MediaWiki Veps labels for Back, Done, Error, Version and Create. Verify the distinct plural errors label against Veps dictionary declension. Preserve placeholders and existing correct labels.
Thanks to xet7 !
Use attested native calendar and country vocabulary instead of English seeds. Exact Islamic name follows Unicode CLDR; composed Chinese and Japanese names need fluent review. Positive and distinct-calendar regressions pass with full correction ledger.
Use Unicode CLDR native Tifinagh vocabulary for Calendar, Time, Today, Day, Week and Month. Preserve existing correct calendar values and verify exact vocabulary and script in the full correction ledger.
Use IRCAM-attested Standard Moroccan Tamazight labels for Title and Language. Preserve correct-language translations elsewhere and add positive vocabulary and negative Arabic-script checks.
Use attested native Persian and Coptic names with existing calendar vocabulary, retaining Jalali as a proper name. Composed calendar names need fluent review. Positive and negative vocabulary checks pass with exact correction provenance.
Replace English Islamic civil with the localized Unicode CLDR Kashmiri name. Check exact native vocabulary and that the civil variant remains distinct from the general Hijri calendar. Other two Kashmiri Hijri findings remain pending.
Replace English and Italian calendar seeds with Tibetan labels, preserving Jalali, Hijri and ISO identifiers. Distinguish tabular epochs and lunar sighting with dictionary-supported vocabulary. Technical compositions and transliterations have low confidence and need fluent review. Correction tests pass; Member Settings UI coverage is added and syntax-checked, browser execution pending.
List successful uploads, failures with reasons, supported retry targets, unsupported local codes and additional catalogue targets requiring local translations. Inspect paginated catalogue read-only, distinguish unavailable support checks, and document requests for new global languages. Verify all reporting offline.
Use attested native words Nimi and kirjamišt. Compact parenthetical sorting wording has low confidence and needs fluent review. Add exact correction and vocabulary checks.
Use native Kelʹ, Lugu and Nimi instead of Finnish seed labels. Correct Painda to the dictionary imperative Paina in existing default-board instructions. Preserve exact correction provenance and add vocabulary regression checks.
Use dictionary-attested Aig, Uzʹ and Tämbei for Time, New and Today. Preserve source keys and record exact corrections with positive and negative vocabulary checks.
Mirror stdout and stderr to local-time status logs, including dry runs and failures, while preserving exit status. Document unsupported Tigre registration and verify logging offline.
Document 37ae64fa8, passing actual startup tests and pending browser execution. Keep the newly observed Uzbek Arabic script issue in the audit. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Resolve yue and wuu to their existing registered variants, and zh-MO to Traditional Chinese. Exercise actual startup autoruns, delayed profile preference, browser languagechange and absence of profile writes. Browser-language checks pass. Arabic Uzbek vocabulary/script remains a separate translation review.
Thanks to xet7 !
Map ru-RU to supported ru_RU and report its file alias instead of uploading twice. Keep unsupported Aromanian failures visible rather than mapping to Romanian. Offline upload and loader tests pass; no uploads were run.
Thanks to xet7 !
Record 1666a2012 and 0c0adb48b, saved preference precedence and pending UI execution. Use the existing fixture user.id in browser coverage. Locale, audit-progress, changelog-format and browser syntax checks pass.
Thanks to xet7 !
Match all browser preferences using existing locale identifiers and explicit standard-to-legacy aliases, including Veps, Venetian, Latin American Spanish and Uzbek scripts. Prefer supported saved profile choices and fall back to English. Respond to browser languagechange without writing a profile choice. Checks cover all 245 locales and alias/error cases. Browser regression added and syntax-checked; execution pending.
Thanks to xet7 !
Map pt-PT to pt_PT and upload the shared target once. Verify that canonical alias targets are registered and loaded while retaining local variant wording. Offline upload and language-loader checks pass; no uploads were run.
Thanks to xet7 !
Document c6e76522d and 16,007 exact correction records, preserving unresolved language reviews. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Replace Indonesian layanan with attested Acehnese peulayanan in the remaining flagged label and two related instructions. Preserve literal Google Cloud menu labels and JSON. Composed technical wording is low confidence; wider mixed-language review remains. Positive and negative correction checks pass.
Thanks to xet7 !
Record 8549b6c4c, cb6830505 and d5363a26b, passing local checks and pending browser verification. Preserve remaining translation findings. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Verify all 245 registered popup locales and every translation file. Resolve regional flags from base languages with explicit legacy and script exceptions; preserve country-before-language order in RTL interfaces. Unit wiring and actual-helper checks pass. Add and syntax-check browser coverage; browser execution remains pending.
Thanks to xet7 !
Use supported fr_BE, fr_CA, km_KH and gug_PY codes. Collapse the Khmer file alias to one target. Keep unsupported Manx and Ladin failures visible; Ladino is a different language. Offline upload regressions pass; no uploads were run.
Thanks to xet7 !
Replace three unflagged Finnish labels and one flagged account instruction with dictionary-based Veps. Preserve valid shared Nimi. Composed username and purpose-clause wording is low confidence; correction regression checks pass.
Thanks to xet7 !
Document 6db460891, preserve valid alternatives and update the correction inventory to 16,000 records. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Restore Gregorian and ISO week detail in both calendar labels and use Tiempo for the alias time-spent board view. Preserve seven valid Spanish wording alternatives. Translation correction regressions pass.
Thanks to xet7 !
Map es-CO to supported es_CO and prefer explicit local mappings when a legacy alias shares the remote code. Report skipped aliases rather than overwriting one target twice. Offline force-upload tests pass; no remote upload was run. Nine local alias differences still need reconciliation.
Thanks to xet7 !
Record 462f3bb78, 14,472 corrected findings, 1,372 pending and 15,997 exact repair records. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Use dictionary-attested country genitives Kitain and Japonijan with the published Veps calendar noun. Positive and negative language regressions pass; composed terminology remains subject to fluent-speaker review.
Thanks to xet7 !
Document 4a06f2abd and the current audit totals, retaining outstanding language review. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Replace four Finnish-seeded findings with dictionary-based Veps text. Preserve the distinction between missing and uncreated users and retain ISO 8601. Composed technical wording is low confidence; fluent-speaker review remains necessary. Translation correction regressions pass.
Thanks to xet7 !
Record 643cabc3c, low-confidence language review and current totals: 14,466 corrected original findings, 1,378 pending and 15,991 exact correction records. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Use attested Veps vocabulary for showing only locked users and confirming all users were unlocked. Preserve the distinction in positive and negative regression checks. Composed plural and technical account wording is low confidence and needs fluent-speaker review; correction suite passes.
Thanks to xet7 !
Document a5577d919 and the 15,989 exact correction records. Original Veps findings and restored translations remain outstanding. Audit-progress and changelog-format checks pass.
Thanks to xet7 !
Use Ližada for Add and Ližatud for Added, following the dictionary conjugation of ližata. Record exact repairs and positive/negative language regression checks. Translation correction suite passes; wider Veps findings remain under review.
Thanks to xet7 !
Reference dated fix 56f8ce913 and record 15,987 correction records. Original pending findings remain 1,380; preserve specialized shade and wider language review requirements.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace eight unflagged Finnish color names with attested Veps vocabulary from the Veps word list. Add positive/negative vocabulary regression checks; specialized shades remain queued for semantic review.
Validation: complete correction-ledger suite passes for exact values, placeholders, JSON examples, key order and merge preservation.
Thanks to xet7 !
Read actual uptime composition and verify päiväd is also the Veps singular partitive, compatible with the counted-duration context. Clarify correction provenance and add positive/negative language-vocabulary assertions for repaired date units.
Validation: full correction-ledger suite passes; broader Veps grammar review remains outstanding.
Thanks to xet7 !
Reference dated fix ffbf2ef72 and record 14,464 corrected findings, 1,380 pending findings and 15,979 correction records. Preserve low-confidence compound terminology and wider review requirements.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace Finnish calendar and Turkic-seeded selector text with Veps. Confirm kalendar' in actual Veps newspaper and corpus usage. Compound selector wording remains low confidence pending fluent-speaker review.
Validation: correction ledger token, JSON example, key-order and merge-preservation checks pass.
Thanks to xet7 !
Reference dated local fix b077128b2 and record 15,977 correction records. Original pending findings remain 1,381; preserve composed-UI inflection and wider linguistic review requirements.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace four unflagged Finnish-seeded date-unit values with Veps vocabulary from the Veps Wikibooks word list. Preserve singular/plural distinction. Composed-UI inflection remains a low-confidence review item.
Validation: full correction-ledger token, JSON example, key-order and merge-preservation checks pass.
Thanks to xet7 !
Reference dated review ad209a3cb, record 179 retained findings and 1,381 pending findings, and preserve remaining linguistic validation scope.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Review the flagged reactivity label against actual Corsican Assembly and native Corsican usage. Reattività is attested Corsican; identical Italian spelling does not justify overwriting compatible wording. Preserve the configuration variable and record the evidence-backed retention.
Validation: audit-progress exact-value classification passes.
Thanks to xet7 !
Reference dated fix 1c53f96ad, correct the broader German-seed review summary and record 15,973 correction records. Original pending findings remain 1,382; restored and unflagged linguistic review continues.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
The retained value was German Zeitplan, not the tool name described by its review. Replace it with Cron, remove the erroneous review and record the exact correction. Add positive and negative regression assertions for the technical name.
Validation: Klingon semantic and complete correction-ledger suites pass.
Thanks to xet7 !
Reference dated fix 003a34cf3 and record all 429 original Venetian findings repaired, 14,463 total corrected findings, 1,382 pending findings and 15,972 correction records. Retain restored-value and low-confidence linguistic review.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace thirty Italian/English-seeded Venetian display, SMTP, WIP and calendar labels. Preserve private-only access, irreversible vote loss, task movement direction and calendar identities. Direct wording and specialized calendar terminology remain low confidence pending fluent-speaker review.
Validation: correction ledger token, JSON example, key-order and merge-preservation checks pass. Original Venetian queue is empty; restored and unflagged values still require review.
Thanks to xet7 !
Reference dated fix 82a9ae61b and record 14,433 corrected findings, 1,412 pending findings and 15,942 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix 8a615aa40 and record 14,418 corrected findings, 1,427 pending findings and 15,927 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix 9054d1ee2 and record 14,403 corrected findings, 1,442 pending findings and 15,912 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated local fix 73c8cb4b0 and record 14,388 corrected findings, 1,457 pending findings and 15,897 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix 3a139c82a and record 14,368 corrected findings, 1,477 pending findings and 15,877 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace twelve Italian-seeded help and control values. Correct modified-date direction to days ago or less, preserve member/assignee union and private/public-only scope, and translate checked items as checklist entries. Direct wording remains low confidence pending fluent-speaker review.
Validation: correction ledger token, JSON example, key-order and merge-preservation checks pass.
Thanks to xet7 !
Reference dated fix 3e91ec423 and record 14,356 corrected findings, 1,489 pending findings and 15,865 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace sixteen Italian-seeded filter and operator-help values. Preserve query syntax, OR behavior, case insensitivity and negated-field meaning; correct created-date direction to days ago or less. Direct wording remains low confidence pending fluent-speaker review.
Validation: correction ledger token, JSON example, key-order and merge-preservation checks pass.
Thanks to xet7 !
Reference dated fix 0bb0c863e and record 14,340 corrected findings, 1,505 pending findings and 15,849 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix d21f4d87d and record 14,325 corrected findings, 1,520 pending findings and 15,834 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix 4171503bc and record 14,313 corrected findings, 1,532 pending findings and 15,822 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix d2f9dad02 and record 14,297 corrected findings, 1,548 pending findings and 15,806 correction records. Preserve outstanding linguistic and restored-value review.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated local fix 7a48f1a32 and record 14,277 corrected findings, 1,568 pending findings and 15,786 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace twenty Italian-seeded admin, archive and upload messages with Venetian. Preserve active/inactive state meanings, offline data-loss warning, HTML tags and size placeholders. Direct wording remains low confidence pending fluent-speaker review.
Validation: correction ledger token, JSON example, key-order and merge-preservation checks pass.
Thanks to xet7 !
Reference dated fix d653f9771 and record 14,257 corrected findings, 1,588 pending findings and 15,766 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix 7615e1916 and record 14,245 corrected findings, 1,600 pending findings and 15,754 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated local fix a617c4300 and record 14,230 corrected findings, 1,615 pending findings and 15,739 correction records. Preserve outstanding linguistic and restored-value reviews.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix ed63d39a8 and record 14,210 corrected findings, 1,635 pending findings and 15,719 correction records. Preserve outstanding linguistic and restored-value validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix a35ca4249 and record 14,190 corrected findings, 1,655 pending findings and 15,699 correction records. Preserve outstanding language and restored-value review.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated local fix a5a956ca3 and record 14,170 corrected findings, 1,675 pending findings and 15,679 correction records. Retain outstanding linguistic and restored-value review.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace twelve Italian-seeded help and display values. Preserve literal search examples, predicate placeholders, descending minus sign, file formats and external menu labels. Direct wording remains low confidence pending fluent-speaker review.
Validation: correction ledger checks pass for tokens, JSON examples, key order and merge preservation.
Thanks to xet7 !
Reference dated fix 8d669c209 and record 14,158 corrected findings, 1,687 pending findings and 15,667 correction records. Preserve outstanding linguistic and restored-value reviews.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix e8f9a898b and record 14,142 corrected findings, 1,703 pending findings and 15,651 correction records. Preserve outstanding linguistic and restored-value review.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix 2bb366f9a and record 14,117 corrected findings, 1,728 pending findings and 15,626 correction records. Document exact filter-example regression coverage and outstanding linguistic review.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Translate Italian filter prose to Venetian and restore exact executable examples, operator spacing, quote delimiters and single backslashes. Extend existing regression coverage to Venetian and the escaped apostrophe example. Direct prose remains low confidence pending fluent-speaker review.
Validation: all correction ledger checks and exact filter examples pass.
Thanks to xet7 !
Reference dated fix 6d05bb764 and record 14,116 corrected findings, 1,729 pending findings and 15,625 correction records. Preserve outstanding language and advanced-filter reviews.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Reference dated fix 2acd6cc83 and record 14,097 corrected findings, 1,748 pending findings and 15,606 correction records, with linguistic review still outstanding.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace twenty-five Italian-seeded activity and insertion labels. Preserve checked/unchecked and complete/incomplete meanings, source placeholders and top/bottom placement; remove the erroneous digit before the subtask placeholder. Direct wording remains low confidence pending fluent-speaker review.
Validation: correction inventory token, JSON example, key-order and merge-preservation checks pass.
Thanks to xet7 !
Reference dated local fix 65f266e36 and record 14,072 corrected findings, 1,773 pending findings and 15,581 exact correction records. Preserve outstanding linguistic validation.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace Italian-seeded activity messages with Venetian while preserving event distinctions, source/destination hierarchy and every interpolation token. Direct kanban wording is low confidence and awaits fluent-speaker review.
Validation: correction ledger checks pass for tokens, JSON examples, key order and merge preservation.
Thanks to xet7 !
Reference dated translation fix 88c871b27. Record 14,047 corrected findings, 1,798 pending findings and 15,556 correction records; distinguish Venetian and Veps from Venda using the language registry.
Validation: audit progress and changelog format pass.
Thanks to xet7 !
Reference dated local fix 180ca33c5 and record 14,034 corrected findings, 1,811 pending findings and 15,543 correction records. Keep restored-value and fluent-speaker validation outstanding.
Validation: audit progress and changelog format pass.
Thanks to xet7 !
Replace 39 Zulu-seeded messages and 18 calendar labels, including three unflagged Afrikaans values, with Tshivenda. Preserve no-undo warnings, private-only access, numeric validation and calendar identities. Low-confidence wording and specialized calendar terminology await fluent-speaker review.
Validation: correction inventory passes token, JSON example, key-order and merge-preservation checks. All original main Venda audit findings are repaired; broader and restored-value review remains outstanding.
Thanks to xet7 !
Update dated audit summary and TODO Later with 13,980 corrected findings, 1,865 pending findings and 15,486 exact correction records. Reference local fix 77bf80f43 and retain fluent-speaker validation requirements.
Validation: audit-progress and changelog-format suites pass.
Thanks to xet7 !
Replace Zulu-seeded shortcut, visibility, SMTP and migration labels with Tshivenda. Preserve display thresholds, ISO 8601 and technical protocol names. Direct wording is low confidence and awaits fluent-speaker review.
Validation: all 15,486 correction records pass placeholder, JSON example, key-order and merge-preservation checks.
Thanks to xet7 !
Record dated fix 35f909774, 13,950 corrected original findings, 1,895 pending and 15,456 exact corrections. Keep remaining review and verification scope open.
Thanks to xet7 !
Replace Zulu-seeded storage, search and size controls with Tshivenda. Preserve S3 URL and region examples, SSL/TLS names and literal server troubleshooting commands. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 4c42a6808, 13,920 corrected original findings, 1,925 pending and 15,426 exact corrections. Keep remaining language review and full audit scope open.
Thanks to xet7 !
Replace Zulu-seeded rule, rescue-dialog and migration confirmation prose with Tshivenda. Preserve literal IDs, keyboard ranges, full restore scope and irreversible or difficult-to-undo warnings. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 0f8751df8, 13,890 corrected original findings, 1,955 pending and 15,396 exact corrections. Keep remaining audit and verification scope open.
Thanks to xet7 !
Record dated fix cc2eaa2bd, 13,860 corrected original findings, 1,985 pending and 15,366 exact corrections. Keep outstanding review and full audit scope open.
Thanks to xet7 !
Record dated fix 28f1db700, 13,830 corrected original findings, 2,015 pending and 15,336 exact corrections. Preserve remaining review and full audit scope.
Thanks to xet7 !
Replace Zulu-seeded validation, keyboard, labels and list messages with Tshivenda. Preserve source tokens, year example, minimum-admin constraint and irreversible list loss warning. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 1baefe89e, 13,805 corrected original findings, 2,040 pending and 15,311 exact corrections. Keep remaining review and full verification scope open.
Thanks to xet7 !
Record dated fix bff84678e, 13,780 corrected original findings, 2,065 pending and 15,286 exact corrections. Keep remaining review and full audit scope open.
Thanks to xet7 !
Record dated fix 1436d81f2, 13,755 corrected original findings, 2,090 pending and 15,261 exact corrections. Keep outstanding language review and full verification scope open.
Thanks to xet7 !
Replace Zulu-seeded verification emails, format errors and permission requirements with Tshivenda. Preserve source tokens, mail line breaks, WIP/JSON/CSV/TSV names and zoom bounds. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 3e7746666, 13,730 corrected original findings, 2,115 pending and 15,236 exact corrections. Keep remaining review and full verification scope open.
Thanks to xet7 !
Replace Zulu-seeded date controls, subtasks and account emails with Tshivenda. Preserve source placeholders, mail line breaks, SMTP/Planning Poker names and distinct time fields. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 59286c27f, 13,705 corrected original findings, 2,140 pending and 15,211 exact corrections. Keep remaining validation and full audit scope open.
Thanks to xet7 !
Replace Zulu-seeded scheduled-job outcomes and custom HTML/JSON controls with Tshivenda. Preserve %{value}, HTML entities, assetlinks.json and success/failure versus pause/resume distinctions. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Replace Zulu-seeded checklist, star, auto-width and template controls with Tshivenda. Preserve enable/disable meanings and source tokens; use lutombo for blue, supported by https://www.justice.gov.za/constitution/SAConstitution-web-ven.pdf . Other wording remains low confidence and open to fluent review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 779dcb02b, 13,630 corrected original findings, 2,215 pending and 15,136 exact corrections. Keep remaining audit and verification scope open.
Thanks to xet7 !
Replace Zulu-seeded background, backup, cleanup, visibility and card settings labels with Tshivenda. Preserve source tokens, HTML emphasis and permanent loss warnings. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix a89ed3821, 13,605 corrected original findings, 2,240 pending and 15,111 exact corrections. Keep remaining review and full audit scope open.
Thanks to xet7 !
Record dated fix b110191f1, 13,580 corrected original findings, 2,265 pending and 15,086 exact corrections. Preserve remaining review and full audit scope.
Thanks to xet7 !
Record dated fix 4b6da7008, 13,564 corrected original findings, 2,281 pending and 15,070 exact corrections. Keep remaining review and verification scope open.
Thanks to xet7 !
Replace Zulu-seeded import, movement, custom-field, workspace and administrator labels with Tshivenda. Preserve interpolation counts, HTML tags and active/inactive state distinctions. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Replace Zulu-seeded reminders, list creation and checklist activities with Tshivenda. Preserve source placeholders, due-soon/now/past distinctions and completed versus incomplete states. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 77997ecb9, 13,520 corrected original findings, 2,325 pending and 15,026 exact corrections. Keep outstanding language review and full audit scope open.
Thanks to xet7 !
Replace Zulu-seeded lockout controls and dated activities with Tshivenda. Distinguish locked/unlocked and known/unknown states; retain source time and card placeholders. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 2f7658de8, 13,500 corrected original findings, 2,345 pending and 15,006 exact corrections. Keep remaining review and verification scope open.
Thanks to xet7 !
Record dated fix 6ced21a16, 13,475 corrected original findings, 2,370 pending and 14,981 exact corrections. Preserve remaining audit and verification scope.
Thanks to xet7 !
Record dated fix 48739c6ac, 13,455 corrected original findings, 2,390 pending and 14,961 exact corrections. Keep remaining review and verification work open.
Thanks to xet7 !
Record dated fix 846fd29ad, 13,433 corrected original findings, 2,412 pending and 14,939 exact corrections. Keep outstanding validation and remaining audit work open.
Thanks to xet7 !
Replace Zulu-seeded card windows, privacy descriptions, invitations and rule actions with Tshivenda. Preserve source tokens, public visibility versus edit permission and top/bottom placement directions. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix bdcb23fd5, 13,418 corrected original findings, 2,427 pending and 14,924 exact corrections. Preserve outstanding review and full audit scope.
Thanks to xet7 !
Replace Zulu-seeded list movement, storage, notifications and user-role explanations with Tshivenda. Preserve the imported-role permission ceiling and restricted-user capabilities. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 67b6d548a, 13,403 corrected original findings, 2,442 pending and 14,909 exact corrections. Keep remaining language and runtime verification scope open.
Thanks to xet7 !
Replace Zulu-seeded operator and archive-status explanations with Tshivenda. Preserve literal examples, angle-bracket arguments, all source placeholders and has-field negation. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 629fb613d, 13,373 corrected original findings, 2,472 pending and 14,879 exact corrections. Preserve remaining review and verification work.
Thanks to xet7 !
Replace Zulu-seeded query instructions and operator help with Tshivenda. Keep literal examples, angle-bracket arguments and source placeholders unchanged. Explain OR versus AND distinctly. Low-confidence prose remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 6ecc8171b, 13,363 corrected original findings, 2,482 pending and 14,869 exact corrections. Preserve remaining review and verification scope.
Thanks to xet7 !
Record dated fix c59c09783, 13,353 corrected original findings, 2,492 pending and 14,859 exact corrections. Keep remaining review and verification work open.
Thanks to xet7 !
Replace Zulu-seeded copy, conversion and deletion prose with Tshivenda. Preserve placeholders, irreversible loss warnings and the AND condition requiring an empty duplicate plus a populated namesake list. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix b2b1752c8, 13,338 corrected original findings, 2,507 pending and 14,844 correction records. Keep language validation and wider audit work open.
Thanks to xet7 !
Record dated fix 6a68c0e37, 13,318 corrected original findings, 2,527 pending and 14,824 exact corrections. Retain outstanding language review and broader audit work.
Thanks to xet7 !
Record dated fix f92cfa5b1 and counts of 13,298 corrected original findings, 2,547 pending and 14,804 correction records. Keep remaining verification and full audit scope open.
Thanks to xet7 !
Replace Zulu-seeded messages directly with Tshivenda. Preserve old and new board, list and lane placeholders, exact checkList token case and percent token counts. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 18429316a, 13,282 corrected original findings, 2,563 pending and 14,788 exact correction records. Preserve remaining validation and repair scope.
Thanks to xet7 !
Write Tshivenda activity prose for attachment, membership, checklist, label and archive actions with all source placeholders intact. Vocabulary is informed by available Tshivenda wordlists and existing kanban context; wording is low confidence and remains open to fluent-speaker review.
Validation: audited correction regressions pass.
Thanks to xet7 !
Record dated fix 9b78486c5 and 13,257 corrected original findings, 2,588 pending and 14,763 correction records. Keep remaining verification and broader audit work open.
Thanks to xet7 !
Replace English Coptic and tabular Hijri labels using existing locale calendar terminology. Preserve civil versus astronomical epoch distinctions. Specialized wording is low confidence and remains open to fluent-speaker review.
Validation: audited correction regressions verify placeholders, examples, key order and newer translation protection.
Thanks to xet7 !
Record dated fix e077f92b9 and 13,251 corrected original findings, 2,594 pending and 14,757 correction records. Keep broader language validation and browser checks open.
Thanks to xet7 !
Replace English Coptic, Buddhist and tabular Hijri labels using existing locale terminology. Retain civil versus astronomical epoch distinctions. Specialized wording is low confidence and remains open to fluent-speaker review.
Validation: audited correction regressions preserve placeholders, examples, formatting and key order.
Thanks to xet7 !
Record dated fix 2a750c70c, 13,241 corrected original findings, 2,604 pending and 14,747 exact corrections. Preserve remaining language-validation and browser-verification work.
Thanks to xet7 !
Replace English Buddhist, Coptic and tabular Hijri labels with locale wording. Keep civil and astronomical epoch variants distinct. Specialized translations are low confidence and remain open to fluent-speaker review.
Validation: audited correction regressions verify placeholders, examples, order and newer translation protection.
Thanks to xet7 !
Record dated fix 205a2317a and counts of 13,233 corrected original findings, 2,612 pending and 14,739 correction records. Preserve remaining language validation and audit scope.
Thanks to xet7 !
Replace English Coptic labels in Setswana and Sesotho and the English civil Hijri label in Sesotho using existing locale calendar terminology. Specialized wording is low confidence and remains open to fluent-speaker review.
Validation: audited correction regressions verify placeholders, examples, formatting and key order.
Thanks to xet7 !
Record dated fix 1b930ff38, 13,230 corrected original findings, 2,615 pending and 14,736 exact correction records. Keep specialized language validation and broader audit work open.
Thanks to xet7 !
Replace English labels with Aymara using existing pachachimpu terminology. Distinguish civil and astronomical tabular epochs from Saudi moon sighting. Specialized wording is low confidence and remains open to fluent-speaker review.
Validation: audited correction regressions preserve tokens, examples and key order.
Thanks to xet7 !
Record dated fix 1044eebc9 and 14,733 corrections. All 829 broader German-identical Klingon candidates are reviewed: 828 repairs and one retained technical name. Fluent review, browser verification and the original multi-language audit remain open.
Thanks to xet7 !
Replace remaining German-seeded operator and predicate keywords with whitespace-free Klingon terms supported by the apostrophe-aware parser. Exercise actual locale values through Query for user, member, assignee, creator, board, swimlane, list, title, description, attachment and checklist searches.
Low-confidence Klingon wording remains open to fluent-speaker review. Audited corrections, tokens and localized parser regressions pass; browser verification remains pending.
Thanks to xet7 !
Allow straight and curly apostrophes in operator names so Klingon and other apostrophe-bearing localized keywords can be parsed. Keep quoted value parsing and unknown-operator errors unchanged.
Validation: actual Query runtime tests cover localized names, quoted values, normal operators, plain quoted text and unknown names; card-number search regressions pass.
Thanks to xet7 !
Record dated fix a24ba752c and 14,696 corrections. The broader Klingon queue now consists of 37 search keyword values; 791 were repaired and one technical name retained.
Thanks to xet7 !
Translate remaining German-seeded storage, scheduling and progress controls directly with placeholders intact. Record Cron as a reviewed technical name rather than replacing its shared spelling. Low-confidence Klingon prose remains open to fluent-speaker review.
Validation: audited correction and Klingon regressions pass.
Thanks to xet7 !
Record dated fix 0db60bab0, 14,658 correction records and 76 remaining broader Klingon findings. Retain unresolved original audit findings and search parser support requirement.
Thanks to xet7 !
Replace German-seeded scheduled-job, migration, filesystem and progress labels directly with Klingon. Preserve product names and interpolation tokens. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction and Klingon regressions pass.
Thanks to xet7 !
Link the incremental import implementation and its real Fossil regression. Update dated translation progress for c950c236e to 14,608 correction records and 126 broader Klingon findings remaining.
Thanks to xet7 !
Use fossil import --incremental when the destination exists, retaining existing history without force overwrite. Re-export selected Git namespaces so repositories created by previous script versions also update without requiring marks files.
Validation: real Fossil 2.28 imports a newly committed Git change, retains old commits and avoids duplicates on a third run. Mock failure and namespace regression checks and Bash syntax pass.
Thanks to xet7 !
Record dated fix 4e1e31327, 14,558 exact corrections and 176 remaining broader Klingon findings. Original pending evidence and the apostrophe parser requirement remain unresolved.
Thanks to xet7 !
Replace German-seeded status, spinner, checklist, attachment and progress controls directly with Klingon. Preserve source placeholders and retain literal URL and Cc syntax. Low-confidence wording remains open to fluent-speaker review.
Validation: audited correction and Klingon regression checks pass.
Thanks to xet7 !
Record dated fix 8a5473c35, 14,508 correction records and 226 remaining broader Klingon values. Track required apostrophe support for translated query operator names.
Thanks to xet7 !
Replace German-seeded search help, report headings, card sorting and swimlane controls; preserve source placeholders. Direct wording is low confidence and remains open to fluent-speaker review. Localized operator names require a separate apostrophe parser fix before replacement.
Validation: audited correction and Klingon regression checks pass.
Thanks to xet7 !
Update dated audit progress to 14,468 corrections and 266 remaining broader Klingon findings. Add a regression distinguishing Sunday from the alternate Saturday name.
Thanks to xet7 !
Replace German-seeded weekday labels, card-view headings, sorting labels and search result counts. Use the Klingon Language Institute Gregorian weekday mapping, including jaj wa' for Sunday; preserve interpolation tokens.
Source: https://www.kli.org/duolingo/say-when-an-event-was-2/
Other prose is low confidence and remains open to fluent-speaker review. Audited correction and Klingon regression checks pass.
Thanks to xet7 !
Record the dated repair commit b7acf3047 and correction inventory of 14,425 values. Keep the broader Klingon review queue at 309 and distinguish it from the original 2,618 pending findings.
Thanks to xet7 !
Replace remaining German-seeded checklist actions, swimlane controls, assignee labels and user-management headings directly with Klingon. Preserve source placeholders and record exact before/after values. Wording is low confidence and remains open to fluent-speaker review.
Validation: Klingon translation and audited correction regressions pass.
Thanks to xet7 !
Set executable permissions on apt-install.sh, delete-tag.sh, fetch.sh, fossil.sh and npm-retry.sh so they can be invoked directly. Script contents are unchanged.
Validation: Bash syntax checks and npm retry and Fossil export regression suites pass.
Thanks to xet7 !
Replace reviewed German-seeded labels directly, preserve dynamic tokens and runtime names, and distinguish completed versus incomplete states and top versus bottom positions. Recorded corrections and Klingon regression checks pass. Low-confidence prose remains marked for fluent-speaker review.
Thanks to xet7 !
Replace reviewed German text, distinguishing assignees from creators, archive from delete, start from due dates, and tracking from notification suppression. Preserve tokens and file formats. Recorded-correction, warning and Klingon regression checks pass. Low-confidence wording remains marked for fluent-speaker review.
Thanks to xet7 !
Resolve the UI repository from the script or a supplied filename, keep temporary files under the repository, and report missing files or tools clearly. Add matching menu and command-line entries on Unix and Windows, documentation, and mocked UI path checks. Menu parity and a real Fossil 2.28 history import pass.
Thanks to xet7 !
Export branch, tag and remote-branch namespaces explicitly instead of all refs. Resolve paths from the script, handle destinations with spaces, preserve existing repositories and propagate Git or Fossil failures. Reproduce the reported warning with real Git and verify a real Fossil 2.28 import preserves history and the release tag.
Thanks to xet7 !
Review common board, workspace, vote and archive controls beyond the original audit queue. Preserve all source tokens and use explicit color references to distinguish hues sharing Klingon color terminology. Regression checks for correction records, warning states, JSON and placeholder inventories pass. Low-confidence language remains marked for fluent-speaker validation.
Thanks to xet7 !
Meteor merges top-level profile objects by publication precedence. Publish the private boardViewPreference field reactively so a narrow or empty profile cannot hide it during impersonation. Preserve pending choices until the private preference catches up, and route the remaining calendar helper through the same resolver. Cover preference precedence, updates, unsets, deletion, observer cleanup and the real impersonation browser path.
Thanks to gleneindre and xet7 !
Fixes#6691,
Repair the final 81 flagged strings, including calendar-system labels, storage authentication help and destructive warnings. Preserve calendar epoch and observation distinctions, invitation tokens and diagnostic commands. Placeholder and correction regressions pass. Low-confidence Klingon wording still needs fluent-speaker review; the broader locale audit continues.
Thanks to xet7 !
Finish setUserId before returning to the client, so subscription recreation cannot race the client identity change. Add a deferred-promise regression and verify switch failures propagate.
Thanks to gleneindre and xet7 !
Fixes#6691,
Keep placeholders, JSON properties and literal query examples intact. Add regression checks for destructive warnings, security states and translation records. Update the resumed audit counts. Klingon prose is low confidence and needs fluent-speaker validation.
Thanks to xet7 !
Resolve missing or invalid profile board views through the browser preference and Swimlanes default without reloading. Publish the authenticated user board-view preference privately, including after impersonation. Add fallback, selector-scope, publication-isolation and browser regressions.
Thanks to gleneindre and xet7 !
Fixes#6691,
Remove competing autofocus from the template search field and require the actual title field to retain entered text. Wait for the expected Meteor user in the browser across refresh initialization. The refresh regression passes ten WebKit repetitions without retries.
Thanks to xet7 !
Extend the URL-prefix regression with preference-preserving reload, actual logout, empty-cookie refresh and invalid-cookie rejection. All three browser checks pass against the current compiled source.
Thanks to xet7 !
Use same-origin cookie endpoints under the configured ROOT_URL path for prefixed deployments. Preserve native server validation, HttpOnly cookies, memory-only credentials and root deployment behavior. Keep browser fixture navigation under its base path.
Thanks to xet7 !
Cancel the header reset link default action before resetting the filter. Require the reset control and assert the document and board remain mounted while the label query is removed.
Thanks to xet7 !
Avoid a second token login while cookie retrieval is still pending. Exercise voting persistence, board title editing and the member archive menu through the current UI.
Thanks to xet7 !
Exclude launcher and ancestor PIDs before expanding abandoned test process trees. A shell command containing the test invocation must not terminate its own parent. Regression checks preserve cleanup of unrelated old tests without signalling real processes.
Record the dated pause and remaining translation validation in the short audit and TODO Later. Group all unreleased calendar, OAuth2, translation and maintainer-tool changes since v11.72, including Playwright and repository mirror updates. Preserve released sections and record the full coverage audit and outstanding checks.
Preserve enabled and disabled states and the opposite click actions. Keyboard noun is attested; assembled shortcut wording is low confidence and requires fluent-speaker review.
Preserve conversion of each text line into one checklist item and the original-order variant. Text-line terminology and assembled phrases are low confidence and need fluent-speaker review.
Preserve all versus completed checklist items and duplicate-empty list conditions. Complete software phrasing is low confidence and requires fluent-speaker review.
Replace nine foreign-language transfer labels and status messages. Preserve ongoing, failed and completed states. Software terminology is low confidence and requires fluent-speaker review.
Replace four German monitoring and refresh strings with Klingon. Software metaphors and complete wording are low confidence and require fluent-speaker review.
Preserve movement and import argument order, source/destination roles, creation, addition and joining. Verify substitutions against activity templates. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve migration operation distinctions, success and failure, completion and stopping all migrations. Use descriptive data-changing task terminology. Assembled technical wording is low confidence and needs fluent-speaker validation.
Preserve pause, resume and start distinctions, operation success or failure, and deletion confirmation. Reuse scheduled-task terminology and attested verbs. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve formatted-date then card-link substitution order and distinguish start, received, due and end dates. Restore exact technical format labels. Assembled date wording is low confidence and needs fluent-speaker validation.
Preserve export format, field inclusion, board/card identity and export inability or failure. Reuse repaired export terminology. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve enrollment, reset and verification actions, exact placeholders and paragraph breaks. Reuse password and message terminology with descriptive link/address metaphors. Assembled wording is low confidence and needs fluent-speaker validation.
Preserve S3 save completion, test-email recipient, invitation actor and account enrollment site. Reuse repaired terminology and exact source placeholders. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve all-card list scope, single additions and Trello import source. Reuse repaired movement, selection and import terminology. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve star-marker actions, count and top-of-list display. Replace German labels using a descriptive star-label metaphor. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve multiple-card window behavior, add/edit form closure and the missing-board placeholder. Reuse existing terminology with descriptive software window and form metaphors. Assembled wording is low confidence and needs fluent-speaker validation.
Preserve member addition/removal, comment counts, irreversible deletion confirmations and existing-user restrictions. Describe restoring the original state for undo warnings. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve label actions and label/card substitution order, plus added-team and organization display position. Reuse existing terminology and plural indefinite agreement. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve each control scope and the ISO 8601 reference. Reuse existing card, list, member and image terminology. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve executable sorting syntax, descending order and number/value placeholder roles. Replace four German search messages. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve storage destinations and singular, board-wide and global movement scopes. Reuse attachment terminology and retain technical backend names. Assembled software wording is low confidence and needs fluent-speaker validation.
Preserve filter criteria, click-to-edit instructions, assignment to me and personal ownership. Clearing removes filter criteria. Assembled software phrasing is low confidence and needs fluent-speaker validation.
Replace five audited German controls, preserving destination, confirmation and inability to export. Correct plural indefinite-subject agreement in both numeric card-sorting labels according to Klingon Language Institute guidance. Assembled software wording is low confidence and needs fluent-speaker validation.
Reuse existing small-message terminology for comments and preserve addition, editing and deletion distinctions. Verify comment text substitution against the activity template. Assembled wording is low confidence and needs fluent-speaker validation.
Preserve import destinations and every old/new movement context placeholder; align duplicate label-removal wording. The import metaphor and assembled movement phrases are low confidence and need fluent-speaker validation.
Preserve member addition versus removal and the exact checklist placeholder capitalization. Reuse card and checklist terminology. Assembled software wording is low confidence and needs fluent-speaker validation.
Replace nine German activity messages while preserving placeholder roles, board context, and addition versus deletion or removal. Reuse existing card, checklist, attachment and label terms. Assembled wording is low confidence and needs fluent-speaker validation.
Preserve existing-account prompts, account creation success and failure, and the ability to log in after creation. Reuse the account borrowing. Software wording is low confidence and needs fluent-speaker validation.
Preserve permission for the user to delete their own account. The account borrowing follows existing controls; the assembled wording is low confidence and needs fluent-speaker validation.
Replace German and French notification labels and retain deletion of all notification messages. Descriptive software wording is low confidence and needs fluent-speaker validation.
Replace three flagged German controls using descriptive height wording and preserve add-below direction. Full phrases remain low confidence and require fluent-speaker validation.
Replace three flagged German labels and distinguish search, board and filter panels. Software descriptions remain low confidence and require fluent-speaker validation.
Replace three flagged German strings while retaining markdown. Descriptive software terminology and full phrases remain low confidence and need fluent-speaker validation.
Replace three flagged German strings while preserving the deletion question and comma-separated example. Full phrases remain low confidence and need fluent-speaker validation.
Replace four labels using existing checklist wording and preserve the activity destination placeholder. Descriptive terminology and full phrases remain low confidence and need fluent-speaker validation.
Replace four flagged German controls while preserving deletion, display, all-card and new-card distinctions. Full phrases remain low confidence and require fluent-speaker validation.
Use descriptive user-configured data-field wording consistently across four labels. Software terminology and full clauses remain low confidence and require fluent-speaker validation.
Replace five German/French labels and preserve the missing-name placeholder roles. Assembled software phrases remain low confidence and need fluent-speaker validation.
Replace six German labels, preserving the deletion question. Software hierarchy terminology and assembled phrases remain low confidence and require fluent-speaker validation.
Replace four flagged German messages and preserve placeholder roles. Software constructions and the subtask term remain low confidence and require fluent-speaker validation.
Replace seven German labels using existing card and attachment terms. Software compounds and full phrases remain low confidence and need fluent-speaker validation.
Replace ten German labels with direct configuration-data wording, retaining S3 and existing workspace, board and organization terms. Full phrases remain low confidence and require fluent-speaker validation.
Replace German labels and a French title, retaining the webhook technical term. Assembled phrases and borrowing inflection are low confidence and require fluent-speaker validation.
Replace six German labels, including unflagged password strings. Assembled software phrases remain low confidence and require fluent-speaker validation.
Keep the tabular calculation and astronomical starting-date distinctions. Assembled phrase requires native-speaker validation and is recorded as low confidence.
Preserve civil versus astronomical starting-date distinctions. Full phrases and calendar-domain terminology require native-speaker review and are recorded as low confidence.
Replace three English labels while preserving the calendar distinctions. Full phrases and the starting-date compound need native-speaker validation and are recorded as low confidence.
Replace English names following existing calendar terminology; preserve Amete Alem. Adjective renderings remain low confidence and need native validation.
Replace Turkish and English text with direct Buryat wording following local calendar terminology. Name renderings and assembled phrases remain low confidence.
Replace nine French labels, including related unflagged strings. Repository borrowing and orphan metaphor remain low confidence; native review required.
Replace four French labels while retaining selectable animation identifiers. Dictionary-based software wording remains low confidence and needs native-speaker review.
Preserve calendar identities, Dangi proper name and Gregorian calendar with ISO 8601 weeks. Assembled labels remain low confidence pending native review.
Preserve label/member action distinctions, first due-reminder placeholders, wish-list example and numeric sum at list top. Assembled wording remains low confidence pending native review.
Preserve old and new time roles and received-date versus card-link arguments. Derived receipt and assembled software wording remain low confidence pending native review.
Preserve operator tokens and example identifiers while replacing French explanations for board, list, creator, member and comment searches. Assembled relative clauses remain low confidence.
Remove stray digit before the list-name placeholder and preserve archive, filter and card/minicard display meanings. Dictionary-based software senses and assembled grammar remain low confidence.
Preserve recipient and URL placeholders and paragraph formatting in enrollment, password-reset and email-verification instructions. Assembled prose remains low confidence.
Use primary Volapük email and sign-in terminology. Preserve site placeholders and reset, verification, failure and account-creation meanings. Assembled grammar remains low confidence.
Replace French and Esperanto titles and warnings. Preserve lookup placeholders, no-undo warning and organization board-removal meaning. Software adaptations and assembled grammar remain low confidence.
Preserve singular, all-board and global attachment scope and filesystem, GridFS and S3 destinations. Dictionary-based filesystem phrase and assembled grammar remain low confidence.
Use checked template and container vocabulary consistently across card, list and board labels. Preserve many-card copy scope. Software adaptations and assembled phrases remain low confidence.
Replace French labels using dictionary vocabulary, including the computer-specific template term. Preserve completed and marked-item filtering distinctions. Derived compounds and assembled grammar remain low confidence.
Preserve team membership blocker, irreversible deletion warnings and the distinction between deleting a team and removing its board assignment. Dictionary-based assembled phrases and software vocabulary remain low confidence.
Replace French and Esperanto team text using dictionary vocabulary. Preserve lookup placeholders and the team-count separator. Assembled grammar and software senses remain low confidence.
Replace six French labels; preserve display destinations and all versus new card scope. Software senses and full phrases remain low confidence pending native review.
Replace six French labels using dictionary vocabulary and consistent local terminology. Preserve action scopes; derived compounds and full grammar remain low confidence pending native review.
Replace five French values and express restoration as undoing archiving. Preserve action direction and placeholders; full grammar remains low confidence pending native review.
Replace five French values while preserving user-defined field distinction and source placeholders. Software terminology and assembled grammar remain low confidence pending native review.
Replace five French values using dictionary vocabulary; preserve error meaning and placeholders. Derived attachment noun and full grammar remain low confidence pending native review.
Use dictionary-attested computer settings term väls in three previously repaired labels. Preserve original provenance records; complete phrases and workspace compound still need native review.
Replace four French messages and preserve checking reversal and placeholder order. Derived nouns and complete grammar remain low confidence pending native review.
Replace four French labels and align workspace wording with repaired actions. Software-settings terminology and assembled phrases remain low confidence pending native review.
Replace three French labels using dictionary vocabulary while retaining technical identifiers. Assembled phrases remain low confidence pending native review.
Replace four French labels and retain empty-list qualifiers. Software duplicate terminology and assembled phrases remain low confidence pending speaker review.
Replace five French labels using dictionary vocabulary. Data import sense, compounds and assembled UI phrases remain low confidence pending native review.
Replace four French labels using dictionary vocabulary. Assembled UI phrases and software-field terminology remain low confidence pending speaker review.
Repair 13 audited values while retaining calendar names. Specialized religious and country adjectives remain low confidence and need further terminology review.
Translate 30 audited values, retaining role distinctions, selection scope and operator placeholders. Full grammar and filtering terminology remain low confidence.
Translate 32 audited values, preserving web identifiers, default dimensions and success/failure states. Full grammar and specialized terminology remain low confidence.
Translate 22 audited values, preserving date states, argument order and due-card permission scope. Full grammar and specialized terminology remain low confidence.
Translate 26 audited values, preserving movement directions, WIP scope and notification states. Full grammar and rule/notification terminology remain low confidence.
Translate 16 audited values while retaining menu labels, file formats and current-user fallback. Full grammar and mapping terminology remain low confidence.
Translate 18 audited values while preserving formats, byte units and field groups. Full grammar and specialized field terminology remain low confidence.
Translate 29 audited values, preserving affected data and paused/failed migration states. Full grammar and migration terminology remain low confidence.
Translate 15 audited controls, preserving format placeholders, whitespace entities and HTML tags. Full grammar and template terminology remain low confidence.
Translate 19 audited date values and two adjacent month controls. Preserve date/card argument order and date types. Received-date terminology, deadline loan and grammar remain low confidence.
Translate 23 audited values while retaining deleted objects, no-undo warnings and archive recovery. Full grammar and technical history terminology remain low confidence.
Translate 24 audited values while preserving role restrictions and prohibitions. Full grammar and specialized assignment phrasing remain low confidence.
Translate 29 activity values, preserving complete context placeholders and movement origins and destinations. Full sentence grammar remains low confidence.
Translate filter prose while preserving operators, examples and exact escape sequences. Use dictionary-supported raw terminology. Specialized wording and grammar remain low confidence pending native-speaker review.
Use dictionary-supported Persian, Chinese, Japanese and Jewish names. Preserve named calendars, civil and astronomical epochs and Saudi lunar observation. Specialized calendar terminology and grammar remain low confidence pending native-speaker review.
Correct movement out of a list and the truncated Excel format name. Preserve authentication optionality, worker restrictions and deletion warnings. Grammar and borrowed technical vocabulary remain low confidence pending native-speaker review.
Correct top versus bottom movement and distinguish checking from unchecking. Preserve rule conditions and placeholders. Grammar and borrowed technical vocabulary remain low confidence pending native-speaker review.
Correct case-insensitive search, creator versus assignee wording and the one-board home limit. Preserve search placeholders and number syntax. Grammar and borrowed technical vocabulary remain low confidence pending native-speaker review.
Distinguish automatic list width from default width and preserve clipboard, template-copy and archive-restoration behavior. Grammar and adapted technical vocabulary remain low confidence pending native-speaker review.
Fix board versus card wording and broken strong tags. Cover HTML tag preservation and malformed markup regressions. Grammar and borrowed technical terminology remain low confidence pending native-speaker review.
Preserve HTML tags and the before/after insertion distinction. Replace foreign-language surrounding text using existing Acehnese terminology and dictionary vocabulary. Grammar and borrowed technical terms remain low confidence pending native-speaker review.
Preserve activity argument order and distinguish clearing a field value from deleting its definition. Use dictionary-supported name, image and position vocabulary. Grammar and borrowed technical terms remain low confidence pending native-speaker review.
Replace Malay and Indonesian activity wording using existing Acehnese terminology and dictionary-supported creation and movement verbs. Preserve every source placeholder. Grammar and borrowed technical vocabulary remain low confidence and need native-speaker review.
Replace fifteen English calendar findings, preserving Dangi, Amete Alem, Minguo and Umm al-Qura names. Distinguish civil and astronomical epochs and Saudi lunar sighting. Specialized terminology and grammar require native-language review.
Replace twelve Polish findings, correcting shortcut list display rather than pinning. Preserve WIP, Lost Cards and shared versus per-swimlane meanings. Specialized terminology and grammar require native-language review.
Replace twelve Polish findings, preserving Trello Butler naming, comma-separated examples and complete/incomplete distinctions. Describe trigger events in the present rather than future tense. Specialized terminology and grammar require native-language review.
Replace twelve Polish findings, preserving MongoDB compact identity, OIDC and operator placeholders. Clarify one line per checklist item and blank-field matching. Specialized terminology and grammar require native-language review.
Replace twelve Polish findings, preserving strict width and CPU threshold limits, product names and pause versus stop meanings. Specialized terminology and grammar require native-language review.
Replace twelve Polish findings, preserving Google Cloud menu labels, JSON/URL names and search operator tokens. Clarify title matching rather than matching a search key. Specialized terminology and grammar require native-language review.
Replace twelve findings, preserving monthly day limits, Azure menu labels and the Persian Jalali identity. Specialized terminology and grammar require native-language review.
Replace twelve Polish findings, preserving date/card placeholder order, API transfer direction and Azure portal labels. Specialized terminology and grammar require native-language review.
Replace twelve Polish findings, preserving placeholders and due versus end date, checklist completion versus reversal, and import direction distinctions. Specialized terminology and grammar require native-language review.
Repair six flagged Polish findings and the associated legal notice link text. Review prefix and link together against their template. Preserve seconds and failure-count distinctions. Specialized wording and grammar require native-language review.
Repair two Polish memory diagnostics and retain the shared technical DDP transport label. Preserve malloc and distinguish current allocation from peak allocation. Specialized wording and grammar require native-language review.
Replace the Azerbaijani calendar setting and align its calendar label with attested Silesian Kalyndŏrz. Calendar setting grammar remains subject to native-language review.
Replace twelve French findings, preserving Lost Cards, URL and ID terminology and shared versus per-swimlane lists. Specialized terminology and grammar require native-language review.
Replace twelve French findings, preserving ISO 8601, SMTP and TLS identifiers and starred-board ordering. Specialized terminology and grammar require native-language review.
Replace twelve French findings, preserving snap and Docker commands, pixel units and WIP maximum wording. Specialized terminology and grammar require native-language review.
Replace twelve French findings, preserving swimlaneId/listId and Lost Cards naming. Retain archived versus non-archived scopes and duplicate-empty-list deletion conditions. Specialized terminology and grammar require native-language review.
Replace twelve French findings, preserving placeholders and login HTML. Retain permanent Planning Poker deletion and PDF download fallback meanings. Specialized terminology and grammar require native-language review.
Replace twelve French findings, preserving Trello and Excel identifiers, byte units and permanent list deletion warning. Specialized terminology and grammar require native-language review.
Replace twelve French findings. Preserve placeholders, shortcut toggle states, permanent label deletion and the requirement for at least one administrator. Specialized terminology and grammar require native-language review.
Replace twelve French findings, preserving the ended predicate and CSV, TSV and JSON identifiers. Retain label text versus list display distinctions. Specialized terminology and grammar require native-language review.
Replace twelve French findings, preserving operators, predicates, argument names and descending sort syntax. Close the unmatched overdue example markdown delimiter. Specialized terminology and grammar require native-language review.
Replace sixteen French findings, preserving search tokens and English example arguments. Clarify OR versus AND combination and double-quoted values. Specialized terminology and grammar require native-language review.
Replace sixteen French findings, retaining Excel naming and distinct creator, owner, member and assignee roles. Preserve insufficient disk space and self-invitation errors. Specialized terminology and grammar require native-language review.
Replace sixteen French findings, preserving email and due-time placeholders and distinct received, start, due and vote end dates. Specialized terminology and grammar require native-language review.
Replace sixteen French findings. Preserve the default logo height, URL and HTML terms, and the empty-list AND matching populated-list deletion condition. Specialized terminology and grammar require native-language review.
Replace sixteen French findings, preserving assetlinks.json, HTML entities and template placeholders. Retain permanent custom-field deletion and history loss warnings. Specialized terminology and grammar require native-language review.
Replace sixteen French findings. Review the assigned-comment role against its source capabilities and checklist close controls against their templates. Preserve the missing-comment placeholder. Specialized terminology and grammar need native-language review.
Replace eight French findings with Breton wording, preserving the due-time placeholder. Specialized terminology and grammatical wording remain subject to native-language review.
Preserve date-first/card-second arguments and distinguish clearing a field value from deleting its definition. Specialized terminology and grammar need language review.
Remove spurious digit before list title placeholder and preserve complete/incomplete actions. Specialized terminology and grammar need language review.
Translate the legal notice prefix together with its rendered label. Preserve failure-window seconds and account change options. Specialized terminology and grammar need language review.
Preserve peak malloc, available, executable, physical and used heap distinctions. Specialized terminology has low confidence and needs language review.
Describe heap garbage overwriting rather than an option named does_zap_garbage. Preserve malloc and MongoDB identifiers. Specialized terminology has low confidence and needs language review.
Preserve board/member-specific storage repairs, data-integrity checks and search field scope. Specialized terminology and grammar need language review.
Preserve administrator-only execution, per-migration execution and board/global attachment scope. Specialized terminology and grammar need language review.
Preserve administrator requirements, distinct account errors and board-scoped storage repairs. Specialized terminology and grammar need language review.
Keep invitation tokens intact and describe all incomplete cards with due dates, without implying they are already overdue. Specialized terminology and grammar need language review.
Preserve linked-card prerequisites, existing-user constraints and irreversible deletion. Specialized terminology and grammatical wording need language review.
Preserve offline data-loss warning, logged-in access and permanent attachment deletion. Specialized terminology and grammatical wording need language review.
Distinguish checklist-item removal from removal of a whole checklist. Preserve tokens and incomplete-state actions; grammatical wording needs language review.
Replace French wording while preserving temporary lockout and known-user distinctions. Security terminology has low confidence and needs language review.
Use dictionary-backed arapapaha and preserve proper names. Specialized labels have low confidence and need language review; three epoch/observation findings remain pending.
Use pachachimpu for calendar and retain borrowed proper names. Specialized labels have low confidence and need language review; system and epoch qualifiers remain pending.
Replace twelve English calendar labels while preserving proper names. Specialized names have low confidence and need language review; epoch and observation qualifiers remain pending.
Preserve the existing civil-calendar translation while closing its variant qualifier. Indian national calendar terminology has low confidence and needs language review; two specialized audit findings remain.
Replace foreign calendar labels while preserving variant names and epoch distinctions. Specialized terminology has low confidence and needs language review.
Replace ten French findings. Preserve zoom limits, CSV and TSV distinctions, disk space failure and exported date categories. Regional terminology requires language review.
Replace twelve French findings. Preserve duplicate-list deletion conditions, subtask landing list and due-date scope and token. Regional terminology requires language review.
Replace twelve French findings. Preserve head and meta identifiers, default logo height and both conditions required for empty duplicate-list removal. Regional terminology requires language review.
Replace twelve French findings. Preserve paused versus failed migration states, irreversible field-history warning, format placeholder and HTML entities. Regional terminology requires language review.
Replace twelve French findings. Preserve newest and oldest sort directions, job failure and success states and cover image meaning. Regional terminology requires language review.
Replace ten French findings. Preserve automatic width state, assigned-card comment permissions and search placeholder. Regional terminology requires language review.
Replace ten French findings. Preserve due-time placeholder, allowed file type distinctions and one URL scheme per line instructions. Regional terminology requires language review.
Replace ten French findings. Preserve activity arguments and distinguish clearing a field value from deleting a field. Regional terminology requires language review.
Replace ten French findings. Preserve time and notification placeholders, correct date and card argument meanings and remove the stray numeral before renamed-list text. Regional terminology requires language review.
Replace twelve French findings. Preserve lockout units and thresholds, account creation behavior and old and new ending-time placeholders. Regional terminology requires language review.
Replace twelve French findings. Preserve memory statistic distinctions and loading indicator identifiers. Describe heap zapping as bit-pattern overwrite rather than an option named does_zap_garbage. Specialized terminology requires language review.
Replace ten French findings. Preserve username placeholder, minimum length, assignee ordering and export permission scopes. Regional terminology requires language review.
Replace twelve French findings. Preserve swimlane archive recovery, logged-in support restriction and board member avatar scope. Regional terminology requires language review.
Replace fourteen French findings. Preserve public board visibility, editing permissions, original checklist order and rule movement targets. Regional terminology requires language review.
Replace twelve French findings. Preserve administrator-only migration permissions, archive restoration guidance and board-scoped versus global attachment actions. Regional terminology requires language review.
Replace twelve French findings. Preserve public-search token, board title placeholder, member fallback behavior and archive recovery instructions. Regional terminology requires language review.
Replace eighteen French findings. Restore source search argument identifiers and distinguish cards with due dates from overdue cards. Preserve invitation tokens and repair behavior. Regional terminology requires language review.
Replace fifteen French findings. Preserve irreversible deletion warnings, linked-card prerequisites and organization and team membership constraints. Regional terminology requires language review.
Replace twenty French findings with Occitan control labels. Preserve top versus bottom actions, administrator permissions and custom HTML boundaries. Regional terminology requires language review.
Replace eighteen French findings with Occitan activity and add-control messages. Preserve notification placeholders, move origins and destinations and checklist arguments. Regional terminology remains subject to language review.
Replace sixteen French findings with Occitan account protection and unlock messages. Preserve known versus unknown user distinctions and confirmation scope. Regional terminology remains subject to language review.
Replace two English calendar labels using the existing Kashmiri calendar spelling. Retain the proper calendar name. Civil, astronomical and sighting descriptions remain pending vocabulary review.
Replace two retained English findings. Preserve Indian national calendar and Saudi lunar sighting meanings. Low-confidence specialized wording requires native-speaker review.
Replace four English calendar findings. Preserve Saudi lunar sighting and astronomical tabular epoch meanings. Low-confidence specialized terminology requires native-speaker review.
Replace retained English prose while preserving every source operator, quoted example, escape sequence and regex. Low-confidence technical wording requires native-speaker review.
Replace twenty retained English findings across both Frisian locale files. Preserve product identifiers and civil, astronomical and lunar observation distinctions. Specialized calendar wording requires language review.
Replace three retained English findings using shared written technical vocabulary consistent with existing locale labels. Preserve product names and Saudi lunar observation meaning. Dialect-specific wording remains subject to native-speaker review.
Translate four retained English findings using simplified Chinese orthography. Preserve product names and lunar observation and astronomical tabular distinctions.
Translate retained English storage and Trello export instructions and the Saudi lunar-sighting calendar label. Preserve product names and source menu identifiers.
Replace seventeen foreign-language calendar findings with Yiddish labels. Preserve distinct civil and astronomical epochs and Saudi lunar sighting. Specialized terminology requires language review.
Replace ten findings, including Hindi rule text and English storage and calendar prose. Restore date format labels exactly without stray separators. Preserve case-insensitive rule meaning and lunar and astronomical distinctions. Specialized terminology requires native-speaker review.
Repair twelve findings across three locale tags, accounting for the shared-file alias. Preserve filter examples and escape sequences. Specialized wording requires native-speaker review.
Replace nine English calendar findings across three Khmer locale variants. Preserve the Indian national, Saudi lunar sighting and astronomical tabular distinctions. Specialized terminology requires native-speaker review; other Khmer findings remain pending.
Replace five English calendar findings with Uyghur labels, preserving civil and astronomical epoch distinctions and Saudi lunar sighting. Specialized terminology requires native-speaker review.
Replace fifteen English calendar findings with Central Kurdish labels. Preserve civil and astronomical epoch distinctions and Saudi lunar sighting. Specialized terminology requires native-speaker review.
Replace seventeen foreign-language calendar findings with Latin labels. Preserve calendar names and distinguish civil, astronomical and lunar observation variants. Specialized terminology remains subject to language review.
Describe the V8 heap overwrite diagnostic according to Node documentation. Match the legal acceptance prefix to the existing plural legal notice label. Leave the shared item example pending review. Low-confidence Neapolitan wording requires native-speaker review.
Replace twenty-seven Italian findings covering date display, settings, migration controls and Trello credentials. Preserve ISO designation, API URL and minimum username length. Low-confidence wording requires native-speaker review.
Replace twenty-five Italian findings covering exports, filters, storage and import instructions. Clarify checked items and minicard label text; preserve search syntax and product names. Low-confidence wording requires native-speaker review; font preview is not certified as a pangram.
Replace twenty-five Italian findings, preserving site placeholders and zoom limits. Clarify email template body and subject labels and remove the stray English word in password reset. Low-confidence wording requires native-speaker review.
Replace sixteen Italian findings, preserving reminder tokens and activity arguments. Correct checklist completion to describe the named checklist rather than a count. Low-confidence Neapolitan wording requires native-speaker review.
Replace ten Italian findings, retaining workspace hierarchy, template container consistency and the HTML body tag. Low-confidence Neapolitan wording needs native-speaker review.
Replace six English findings, preserving Indian national identity and distinct Hijri epochs, Saudi moon sighting and Umm al-Qura. Low-confidence Neapolitan wording needs native-speaker review.
Replace two Italian findings, preserving every field predicate, the negative existence example and legal-notice introduction. Low-confidence Aromanian wording needs native-speaker review.
Replace five Italian and English findings, retaining Trello menu labels and distinguishing remaining-work from completed-work charts. Low-confidence Aromanian wording needs native-speaker review.
Replace twelve Italian and English findings, preserving over-limit warnings and consistent font/text labels. Low-confidence Aromanian wording needs native-speaker review.
Replace nine Italian findings, retaining operator placeholders, login HTML links, overdue meaning and PDF download fallback. Low-confidence Aromanian wording needs native-speaker review.
Replace ten Italian findings, preserving irreversible history loss, all-card action scope and byte units. Low-confidence Aromanian wording needs native-speaker review.
Replace nine Italian findings, retaining self-invitation restrictions, username conflicts and next-week due filtering. Low-confidence Aromanian wording needs native-speaker review.
Replace ten Italian findings, preserving JSON versus schema failures, CSV/TSV identities and authorization restrictions. Low-confidence Aromanian wording needs native-speaker review.
Replace ten Italian findings, preserving activation versus deactivation, filename categories, comment placeholders and Enter key identity. Low-confidence Aromanian wording needs native-speaker review.
Replace nine Italian findings, preserving approaching/current/past deadlines, all placeholders and HTML closing tags. Low-confidence Aromanian wording needs native-speaker review.
Replace ten Italian findings, preserving seconds units, failed-login thresholds and old/new time placeholders. Low-confidence Aromanian wording needs native-speaker review.
Replace nine Italian findings, retaining public view versus member edit permissions, removal notifications and shortcut actions. Low-confidence Aromanian wording needs native-speaker review.
Replace ten Italian findings, preserving top/bottom destinations, archive restoration, member removal and rule fragments. Low-confidence Aromanian wording needs native-speaker review.
Replace two Italian invitation messages, preserving all interpolation tokens and literal newline sequences. Low-confidence Aromanian wording needs native-speaker review.
Replace six Italian findings, preserving administrator versus member requirements, linked-card deletion ordering and WIP identity. Low-confidence Aromanian wording needs native-speaker review.
Replace six Italian findings, preserving all-card versus new-card behavior, GridFS identity and board placeholders. Low-confidence Aromanian wording needs native-speaker review.
Replace six Italian findings, preserving label and attachment actions, format placeholders and the HTML body tag. Low-confidence Aromanian wording needs native-speaker review.
Replace six Italian findings, retaining known-user versus nonexistent-user conditions and failed-login lockout meaning. Low-confidence Aromanian wording needs native-speaker review.
Replace six English calendar findings, preserving civil and astronomical epochs, Saudi moon sighting and Umm al-Qura identities. Aromanian wording has low confidence and needs native-speaker review.
Replace ten English calendar names with Aromanian wording, retaining calendar identities. Replacements have low confidence and need native-speaker review.
Translate the remaining English heap label using the documented V8 bit-pattern overwrite meaning. Ladin wording has low confidence and needs native-speaker review.
Replace twenty-six Italian and English findings, retaining API URLs, minimum username length and distinct Hijri variants. Low-confidence Ladin wording needs native-speaker review; one technical heap label remains pending.
Replace seventeen Italian findings, preserving endpoint examples, AWS menu names and WIP identifiers. Ladin wording has low confidence and needs native-speaker review.
Replace nine Italian findings, preserving the value placeholder, HTML/JSON terminology and database identities. Ladin wording has low confidence and needs native-speaker review.
Replace six Italian findings with Ladin wording, preserving distinct pause, resume and start failures. Replacements have low confidence and need native-speaker review.
Replace six wrong-language findings, retaining checklist count formatting, deletion confirmation and Persian calendar identity. Replacements have low confidence and need native-speaker review.
Replace six Italian findings while preserving due-time placeholders, blob container identity and file counting meaning. Replacements have low confidence and need native-speaker review.
Replace six Italian findings, preserving field placeholder order, closing body tag and system-wide announcement status. Replacements have low confidence and need native-speaker review.
Replace six Italian findings while preserving reminder tokens and checklist completion action semantics. Replacements have low confidence and need native-speaker review.
Replace six mixed-language findings while retaining native/detached context distinctions, malloc and RSS identities. Technical wording has low confidence and needs native-speaker review.
Replace five mixed-language findings while preserving spinner names, DDP_TRANSPORT and malloc. Technical wording has low confidence and needs native-speaker review; the garbage-zapping finding remains pending.
Replace three wrong-language findings while preserving activity placeholder order. Ladin replacements have low confidence and require native-speaker review.
Replace nine English findings, preserving lunar sighting, civil versus astronomical epochs, Umm al-Qura and Minguo identities. Wording needs native-speaker review.
Replace eight Italian findings, preserving server log commands, SSL/TLS, mandatory secret keys and keyboard Enter instructions. Wording needs native-speaker review.
Replace eight Italian findings, preserving endpoint examples, region codes, AWS menu names and secret-key versus access-key meanings. Wording needs native-speaker review.
Replace eight Italian findings while preserving domain syntax, four-digit years, administrator requirements and irreversible list deletion. Wording needs native-speaker review.
Replace eight Italian findings, preserving imported/unmatched count tokens and distinct ZIP size, read and import failures. Wording needs native-speaker review.
Replace ten Italian findings, retaining zoom bounds, authorization restrictions and all export date and person categories. Wording needs native-speaker review.
Replace eight Italian findings, preserving logo height defaults, image versus link URLs and text-only database migration scope. Wording needs native-speaker review.
Replace eight Italian findings, preserving the value format token, HTML tag names and distinct image versus link URL controls. Wording needs native-speaker review.
Replace eight Italian findings while retaining paused versus failed migrations, assetlinks.json and keyboard Enter behavior. Wording needs native-speaker review.
Replace eight Italian findings while retaining destructive-action confirmations and distinct delete, pause and resume failures. Wording needs native-speaker review.
Replace eight Italian findings while preserving Azure menu labels, background size tokens and deletion confirmation. Wording needs native-speaker review.
Replace ten Italian findings, restoring incomplete-marking and field-unsetting actions while retaining placeholder order and the body closing tag. Wording needs native-speaker review.
Replace eight Italian findings while preserving reminder timing, old/new date tokens and checklist action semantics. Wording needs native-speaker review.
Replace ten mixed-language findings, preserving reactivity identifiers and resident versus heap memory distinctions. Technical wording has low confidence and needs native-speaker review.
Replace eight Italian metric labels while retaining native versus detached contexts and available, executable, physical and used memory distinctions. Technical wording has low confidence and needs native-speaker review.
Replace ten mixed-language findings, preserving DDP_TRANSPORT, spinner names and malloc. Runtime terminology has low confidence and needs native-speaker review.
Replace fifteen mixed-language or English findings, restore account anonymization meaning and distinguish sighting and astronomical-epoch calendars. Wording remains subject to native-speaker review.
Replace fifteen mixed-language findings while preserving API URLs, placeholders and the requirement for both credentials. Wording remains subject to native-speaker review.
Replace twelve mixed-language findings while preserving storage names, read-enabled selection and distinct completed and stopped states. Wording remains subject to native-speaker review.
Replace twelve mixed-language findings, preserve label placeholders and domain syntax, and retain the requirement for at least one administrator. Wording remains subject to native-speaker review.
Replace twelve mixed-language findings while retaining ZIP rejection reasons, import/export selection behavior and deferred member mapping. Wording remains subject to native-speaker review.
Replace twelve mixed-language findings and restore the days-ago-or-less meaning for created and modified searches. Preserve operator tokens, argument examples and optional server key-file instructions. Wording remains subject to native-speaker review.
Translate three wrong-language findings, preserving successful email sending and site-name placeholder in the verification subject. Wording remains subject to native-speaker review.
Translate four mixed-language findings, preserving voting end date and invitation-domain authorization when self-registration is disabled. Technical wording remains subject to native-speaker review.
Translate four mixed-language findings, preserving the due-date change count placeholder, empty due-card state and drag-to-resize interaction. Wording remains subject to native-speaker review.
Translate four mixed-language findings, preserving watch disablement, label/member action clarification and dragging to resize the left menu. Wording remains subject to native-speaker review.
Translate four mixed-language findings, preserving save success/failure and avatar import/export disablement distinctions. Wording remains subject to native-speaker review.
Translate three mixed-language findings, preserving default authentication method and the storage destination for newly uploaded attachments. Wording remains subject to native-speaker review.
Translate four mixed-language findings, preserving text-data scope, database destinations and version names, migration completion and custom web manifest enablement. Technical wording remains subject to native-speaker review.
Translate five mixed-language findings, preserving Enter key, HTML link/meta/head identifiers and custom help URL meaning. Technical terminology remains subject to native-speaker review.
Translate five mixed-language findings, preserving retry versus resume behavior and failed versus paused migration states. Wording remains subject to native-speaker review.
Translate five mixed-language findings, preserving paused, resumed and started states and distinguishing failures from successful actions. Wording remains subject to native-speaker review.
Translate six mixed-language findings, preserving fading rather than deletion, three aging tiers, custom-field editing and complete/incomplete distinctions. Wording remains subject to native-speaker review.
Translate five wrong-language findings, preserving the size template token, backup-selection prerequisite and attachment-count meaning. Wording remains subject to native-speaker review.
Translate five mixed-language findings, preserve avatar size placeholder and restore exact Azure menu labels while translating user-specific prose. Wording remains subject to native-speaker review.
Translate five wrong-language findings, preserving positive-limit validation, save success/failure distinction, storage path meaning and one URL scheme per line. Wording remains subject to native-speaker review.
Translate eight wrong-language findings, preserving custom field placeholders, the literal closing body tag and active system-wide announcement meaning. Wording remains subject to native-speaker review.
Translate eight Italian or mixed-language activity messages, preserving positional placeholders and checklist completion, date changes, movement and label removal meanings. Wording remains subject to native-speaker review.
Replace twelve mixed-language values with Romansh, preserving temporary lockout causes, user unlock scopes, seconds units and due-time placeholders. Wording remains subject to native-speaker review.
Replace twelve Italian or mixed-language labels with Romansh, preserving activity placeholders, spinner names, DDP_TRANSPORT and malloc identifiers. Runtime terminology is low confidence and requires native-speaker review.
Translate the two flagged English values, preserving CPU and OS acronyms plus filter operators and literal examples. Technical wording is low confidence and requires native-speaker review.
Translate three English calendar labels using existing Maramataka terminology. Preserve national, moon observation and astronomical epoch distinctions. Technical wording is low confidence and requires native-speaker review.
Translate ten flagged labels using existing Kalendarju terminology, correct Persian identification, and preserve calendar identities, sighting and epoch distinctions. Technical wording remains subject to native-speaker review.
Translate five English calendar labels and soft WIP wording. Retain the valid SMTP Test-E-Mail subject after contextual review. Technical calendar wording remains subject to native-speaker review.
Translate eight English labels across four Uzbek locales using their existing Latin-script terminology. Preserve Indian national and Saudi moon-sighting meanings.
Translate Saudi sighting and tabular astronomical-epoch labels using existing Burmese calendar terminology. Technical epoch phrasing is low confidence and requires native-speaker review.
Translate Saudi moon-sighting and tabular astronomical-epoch labels using existing Assamese calendar terminology. Epoch phrasing is low confidence and requires native-speaker review.
Translate three English labels and correct the adjacent civil-epoch label which incorrectly referred to an epic poem. Preserve calendar method and epoch distinctions. Technical wording is low confidence and requires native-speaker review.
Translate Indian national and Saudi Hijri calendar labels using existing Pashto terminology and retain moon sighting. Wording remains subject to native-speaker review.
Translate the Saudi sighting and tabular astronomical-epoch labels using existing Amharic calendar terminology. Technical epoch wording is low confidence and requires native-speaker review.
Translate three English calendar labels using existing protyka terminology and retain national, moon observation and astronomical epoch distinctions. Technical wording is low confidence and requires native-speaker review.
Translate English labels and adjacent civil-epoch wording in both Zulu locales, preserving moon observation and astronomical distinction. Remove duplicate closing parentheses in Umm al-Qura labels. Epoch phrasing is low confidence and requires native-speaker review.
Replace the English label using existing Somali calendar terminology and preserve moon sighting as the method. Wording remains subject to native-speaker review.
Translate three English calendar labels using existing Calannariu terminology, retaining Indian national, Saudi moon sighting and tabular astronomical epoch meanings. Wording requires native-speaker review.
Translate three English calendar labels while retaining Indian national, Saudi moon observation and tabular astronomical epoch meanings. Technical wording is low confidence and requires native-speaker review.
Translate the English Saudi label and four adjacent French Hijri labels into Haitian Creole. Preserve calendar methods and distinct epochs. Epoch wording is low confidence and requires native-speaker review.
Translate the flagged Indian national and Saudi moon-sighting labels, plus adjacent English civil and astronomical epoch wording. Technical epoch phrasing is low confidence and requires native-speaker review.
Translate English filter instructions while preserving operators and literal examples. Retain two cloud product names with valid danda punctuation after review. Technical wording requires native-speaker review.
Translate the Indian national and Saudi Hijri labels using existing tanggalan terminology and retain observation of the moon. Wording remains subject to native-speaker review.
Translate fifteen English labels using the existing kalendaryo terminology, preserving calendar names, moon sighting and distinct civil and astronomical epochs. Technical wording requires native-speaker review.
Replace English labels while retaining Saudi moon sighting and the tabular astronomical epoch. Technical calendar wording remains subject to native-speaker review.
Translate five English calendar labels with explicit Saudi Arabia and crescent observation. Retain thirteen official cloud product names with valid Chinese punctuation.
Translate Saudi moon-sighting and tabular astronomical-epoch labels. Retain six Japanese cloud product names with valid punctuation after review. Technical calendar wording remains subject to native-speaker review.
Translate the Indian national and Saudi Hijri calendar labels using existing Turkmen calendar terminology. Preserve the moon-sighting distinction; technical wording remains subject to native-speaker review.
Preserve Saudi lunar observation and tabular astronomical epoch; retain product names with valid Hindi punctuation. Hindi technical wording needs native-speaker review.
Preserve operators, quoted values, escaping, evaluation order and regex examples in both Welsh locales. Welsh technical wording needs native-speaker review.
Preserve Saudi lunar observation and tabular astronomical epoch distinctions in both Welsh locales. Welsh technical wording needs native-speaker review.
Preserve operators, quoting, escaping and regex examples across all three locales; retain Saudi lunar-observation distinction. Azerbaijani technical wording needs native-speaker review.
Preserve missing-team token, default theme behavior and requirement for both API key and token with token generation location. Aragonese wording needs native-speaker review.
Preserve provider names and AWS navigation labels; distinguish secret and access keys and retain valid region and path-style labels. Aragonese wording needs native-speaker review.
Preserve Monday-through-Friday schedule and distinguish any-label addition from removal and checklist from checklist-item conditions. Aragonese wording needs native-speaker review.
Preserve MongoDB GridFS name and distinguish compact action from completion, left movement and disabling multi-selection. Aragonese wording needs native-speaker review.
Preserve JSON/SVG and JSON/ZIP alternatives and distinguish uploaded archive reading failure from general import failure. Aragonese wording needs native-speaker review.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Correct 14 reviewed values, restoring no-edit restrictions, label range, member notifications and archived entity types while preserving field identifiers.
Thanks to xet7 !
Correct 16 reviewed values, preserving editing restrictions, invitation meaning, movement direction, unchecking and current date/time scope.
Thanks to xet7 !
Correct 14 reviewed values. Preserve assigned-only visibility, creator-or-member notifications, checklist line order and count placeholders.
Thanks to xet7 !
Correct 12 reviewed values. Preserve board/all-attachment scope and storage identifiers, and replace legal-case wording with card and board terminology.
Thanks to xet7 !
Correct 16 reviewed values. Preserve board-departure scope, irreversible list deletion, byte units and batch limits without inventing Amazon-cloud requirements.
Thanks to xet7 !
Correct 15 reviewed values, restoring checklist and attachment meanings and export direction while preserving literal Trello menu names.
Thanks to xet7 !
Correct 14 reviewed values. Preserve email placeholders, invitation rather than full-access promises, and permitted incomplete-card scope.
Thanks to xet7 !
Correct 16 reviewed values, preserving URL rather than Internet-only meanings, logo default height, duplicate-list conditions and linked-card deletion order.
Thanks to xet7 !
Correct 20 reviewed values. Restore board, member and assignee terminology and distinguish deleting a checklist from deleting one item.
Thanks to xet7 !
Correct 18 reviewed values. Restore URL-scheme rather than Internet-site meaning, new-card field scope, scheduled results and board-icon actions.
Thanks to xet7 !
Correct 16 reviewed values. Distinguish inactive accounts from payroll status and clearing field values from deleting fields. Preserve activity arguments and HTML delimiters.
Thanks to xet7 !
Replace 18 Serbian-seeded values with Croatian wording. Restore V8 zap-pattern and resident-set meanings using official Node documentation.
Thanks to xet7 !
Correct the final 28 flagged values, including swimlane warnings, shortcuts, voting, WIP limits and advanced filter prose. Preserve executable examples and technical identifiers.
Thanks to xet7 !
Correct 18 reviewed values and retain two correct Macedonian sidebar imperatives. Restore parent-card, checklist, field sum and filter meanings.
Thanks to xet7 !
Correct 20 reviewed values. Preserve endpoint examples and troubleshooting commands; restore description/custom-field search scope, local MinIO support and swimlane dimensions.
Thanks to xet7 !
Correct 20 reviewed values. Restore all entity types, non-archived scope, duplicate-empty-list conditions and undo warning while preserving storage field identifiers.
Thanks to xet7 !
Correct 20 reviewed values. Preserve positive-integer limits and login links, distinguish organizations from legal parties, and describe invitation rather than guaranteed full access.
Thanks to xet7 !
Record dated corrections, their local commit and remaining counts, with regressions for export direction and literal vendor menu names.
Thanks to xet7 !
Correct 16 reviewed values, including export menu wording, member mapping, attachment archives, invalid filenames and registration invitations. Preserve literal Trello menu names.
Thanks to xet7 !
Correct 20 reviewed values. Distinguish dated cards from completed cards, preserve private/public board meanings and restore checklist, attachment and member terminology.
Thanks to xet7 !
Record the dated 12-value Macedonian operator repair, its local commit, verified totals and remaining findings. Add positive and negative checks for executable field syntax and label matching meaning.
Thanks to xet7 !
Correct 12 reviewed values while preserving account, board, invitation-code and URL placeholders. Restore invitation meaning without granting unrequested full access.
Thanks to xet7 !
Correct 15 reviewed values. Distinguish due, end and received dates, restore card creator and sorting meaning, and preserve source placeholders.
Thanks to xet7 !
Correct 20 reviewed values. Preserve the two required duplicate-list deletion conditions and restore organization, team and kanban terminology.
Thanks to xet7 !
Correct 25 reviewed values. Restore active/inactive account meaning instead of payroll wording, and verify actual rendering of all four date activity types.
Thanks to xet7 !
Correct 25 Bulgarian- and Serbian-seeded values. Check V8 metric meanings against official Node documentation and preserve source tokens and technical identifiers.
Thanks to xet7 !
Correct 22 reviewed values, including list and swimlane labels. Restore checklist removal meaning while preserving source placeholders and verifying exact repair values and JSON ordering.
Thanks to xet7 !
Correct four SMTP subject compounds and retain four individually reviewed valid soft WIP labels. Verify exact correction and review values; all four German audit queues are resolved.
Thanks to xet7 !
Correct 35 reviewed Czech-seeded values, preserving source placeholders and link markup. Verify vocabulary, exact values, key order and repair behavior.
Thanks to xet7 !
Correct 25 reviewed values. Distinguish members and assignees, end dates and due dates, while preserving literal query syntax and vendor menu labels.
Thanks to xet7 !
Correct 20 reviewed values. Preserve query operators and examples while restoring Boolean explanations and the source meaning that text searches ignore letter case.
Thanks to xet7 !
Correct 43 reviewed values and retain two valid template-variable hints. Preserve exact source placeholders and verify native wording with the translation repair and review suites.
Thanks to xet7 !
Replace English advanced-filter prose in seven locale files while preserving exact executable examples and escapes. Translate Arabic Trello instructions while retaining literal vendor menu names. Verify all seven audit queues are resolved.
Thanks to xet7 !
Replace Italian seed wording and English help prose in invitations, imports, permissions, search, administration and archive controls. Preserve query syntax, JSON fields and sprintf argument order. Translate both remaining Hijri variants and register browser coverage.
Thanks to xet7 !
Restore Romanian wording for account protection, activity messages, archive actions and board settings in both Romanian locales. Preserve interpolation tokens and verify real sprintf rendering without the stray subtask digit.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Remove nested date popup height limits and excess spacing, keep the popup within the viewport and add a bottom-right resize handle. Capture pointer drags so resizing cannot close the popup and support arrow-key resizing with content and viewport limits. Extend documentation and regression coverage.
Thanks to xet7 !
Keep the selected calendar grid visible on opening and after selecting a day, including for Gregorian dates. Stack popup fields, size day buttons within their cells and show only hour/minute dropdowns while retaining the hidden combined value for existing save handlers. Update documentation and popup regressions.
Thanks to xet7 !
Apply the selected calendar to shared date displays, calendar month views and date inputs. Provide mouse and keyboard date navigation and hour/minute selection while preserving native date storage. Document the supported offline calendars and add display, picker and browser regressions.
Thanks to mimZD and xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Use a Node-compatible HTML sanitizer so both attachment modes complete instead of throwing at the first HTML-bearing card. Abort partial HTTP transfers on failure and cover complete JSON, attachment bytes and browser downloads.
Thanks to xet7 !
Pulled from Transifex and merged per key. Correct-language translations
were kept (af, az, be, bg, ca, ca_ES, cmn, cs, cy, el, fy, hr, it, ro, sr,
tlh, ug, wa-RR, yi, the en-* variants and others). Wrong-language values
were rejected and the previous correct-language value restored: Indonesian
in Acehnese (ace: Leubeh, Teuks, Sambongan seuemah, Hana nyang geutanyong,
Hana label, Jitôh uroe nyoe, Batai); Persian in Arabic (ar, ar-DZ, ar-EG:
due-today and no-assignee, plus the same strings already sitting in
filter-due-today and filter-no-assignee); Modern Standard Arabic and
Persian in Moroccan Darija (ary: كتر, كل نهار, كل سيمانة, كل شهر, and the
Darija no-assignee); Spanish in Asturian (ast-ES: Testu, Ensin asignar,
Ensin etiqueta, Encaboxar), Valencian (ca@valencia: Text lliure) and
Esperanto (eo: Nuligi); a garbled Turkmen cancel (tk_TM: Ýatyr); Latin
script in the Arabic-script Uzbek locale (uz-AR). Rewritten, low
confidence: Breton no-assignee "Den ebet deverket" (French replaced),
Veps cancel "Hül'gäta" (Finnish replaced; the old value was Venda),
Darija no-label "ماكاينش علامة" and due-today "خاصو اليوم". Kept but
noted: Occitan "Tornar" and Italian "Cancella" for cancel are the right
language with a doubtful meaning. A guard test pins the rejected values.
Thanks to translators and xet7 !
The default of CARD_LAYOUT and MINICARD_LAYOUT - what a board with no
stored cardFieldOrder / minicardFieldOrder renders, and what
applyLayoutOrder() falls back to for the keys a stored order does not
name - is now pinned literally to the render order of cardDetails.jade
and minicard.jade at 59f7d61df, the commit before #4448 made fields
orderable. Reading those templates gives exactly the sequence the layout
module already holds, so no board changes shape; the module, the tests
and the docs now say where that order comes from and a new suite pins
both sequences so a reshuffle cannot pass by reshuffling the template
with it. The two fields newer than that commit stay beside their
closest older neighbour: Text notes in the card's tail, Swimlane name
last on the minicard.
Thanks to xet7 !
The Board Settings menu (boardMenuPopup) is now four groups divided by a
rule, top to bottom:
Rules, Change color, Change Background Image
---
Board View, Swimlane, List, Card
---
Export, Import, Notifications, Outgoing Webhooks
---
Archived items, Move Board to Archive
Before, Archived items sat second in the first group, Notifications sat
among the colours, and Move Board to Archive was alone at the end. Every
entry keeps the guard it had: Rules, Change color, Change Background Image,
Board View, Swimlane, List, Notifications, Outgoing Webhooks and Move Board
to Archive are board-admin only, Export and Import stay behind withApi /
exportDisabled / canImportIntoBoard, Card stays open to any board member,
Archived items to everyone, and Move Board to Archive stays off the
templates board. No translation keys are added.
Two entries were not in the requested list and are kept where they fit:
Import (js-import-into-board), directly under Export in the third group,
and Archived items (js-open-archives), which is the "Archive" of the list,
opening the fourth group above Move Board to Archive.
tests/boardMenuOrder.test.cjs derives the sequence of entries and rules
from the jade and pins it exactly, pins each entry's guards so a reorder
cannot loosen who sees what, and pins the diagram in
docs/Features/Board/Board-View-Settings.md to the same order.
tests/boardSettingsSwimlaneListCard.test.cjs now expects two rules between
Card and Move Board to Archive, one under each group, and never two in a
row.
Thanks to xet7 !
A reported test environment (mongo:8.2.2 in Kubernetes) filled its data
volume: the checkpoint's fdatasync returned ENOSPC, WiredTiger panicked and
mongod aborted - and then it kept failing on every start, with the disk long
since freed. MongoDB 8.2 keeps a throwaway WiredTiger instance under
<dbPath>/_tmp/spilldb for queries that spill to disk and empties it itself on
each start; after the abort that emptying failed ("Failed to clear dbpath of
the internal WiredTiger instance: Directory not empty"), mongod opened the
half-emptied directory, found no version file, reported "Failed to open the
spill WiredTiger instance ... database corruption detected" and fasserted.
Nothing retries, so the pod restarts forever. The data itself is intact;
deleting that one directory is the whole fix.
- snap-src/bin/mongodb-control deletes _tmp/spilldb before every mongod
start (no mongod is running at that point, and mongod recreates it), and
its start-failure handler recognises the log line and names the directory.
The snap ships MongoDB 7 today, so this is a no-op until it does not.
- Admin Panel / Problems: the db.restart row now says what a "No space left
on device" abort means for a full disk as well as for a network
filesystem, and both it and db.disk-space name the exact spill directory
to delete when MongoDB 8.2 will not start afterwards. The probe looks the
data directory up once and passes it to both rows.
- docs/Databases/MongoDB/Storage-Requirements.md gets the log signature of
both stages, why the second one never ends, the one command, what must
not be touched, and that Docker/Kubernetes users run it themselves since
the database container is MongoDB's own image.
- tests/databaseHealth.test.cjs pins the spill path, both rows' advice, the
probe wiring, the snap's pre-start deletion (before the first start, after
the running-instance check, and the only recursive delete apart from the
existing FerretDB reset) and the documentation.
Thanks to xet7 !
"WIP Limit Groups" was a fourth top-level entry of the Board Settings group,
between List and Card. A group most often caps one swimlane's lists
together, so it is now a row of the Swimlane settings popup: Board Settings
/ Swimlane / WIP Limit Groups. The row opens the unchanged wipLimitGroupsPopup
stacked on the Swimlane popup, so its back arrow returns there. No new
translation keys; the existing wip-limit-groups key is reused.
tests/boardSettingsSwimlaneListCard.test.cjs pins the row in the Swimlane
popup and its single handler, and that the top-level Board Settings list no
longer carries the entry. Docs updated to the new path.
Thanks to xet7 !
The v11.70 bump regenerated public/api/wekan.yml and wekan.html on origin
while the local REST API commits had regenerated them against v11.67; the
rebase kept the local spec, so it is rebuilt here with the released version
and the new routes together.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Board Settings / Card was a three-column table (Show on Card, Show on
Minicard, the name) with a separate "Card field order" list of arrows at the
bottom that reordered five sections of the opened card. It is one heading,
"Card field order", over two lists now: "Show on Minicard" in the board's
minicard order and "Show on Card" in its card order, every row of either
`[checkbox] [up] [down] icon label`. The checkbox is whether that side shows
the field, the arrows move it on that side only, and the icon and name are
the field's own. The two lists are independent because the two orders are: a
field can be third on the minicard and last on the card.
models/lib/cardFieldOrder.js is the arithmetic, pure and tested without
Meteor: each surface is a fixed head, reorderable sections of fields, and a
fixed tail. A field moves within its section; at the section's edge it moves
the whole section; a section's header (Labels, Members, Sort number,
Description title) stays first. What is stored is one flat array of field
keys per surface - `cardFieldOrder`, which the first #4448 filled with five
section keys that stay valid and expand to what they rendered (Members
carried Dependencies and Sort, Custom Fields carried Vote/Poker), and the new
`minicardFieldOrder`. Two board setters normalise before storing; the update
allow rule keeps them to a board admin. The REST cardFieldOrder endpoints
still speak in section keys, eight now.
cardDetails.jade renders its eight sections in the board's order and, inside
Labels, Dates, Members, Sort and Vote/Poker, the fields in theirs;
Dependencies and Sort are their own templates. minicard.jade renders every
block under the title through the minicard order, with the dates line and
the badge strip ordering their own fields. Every gate is unchanged.
The popup's rows are a table, models/lib/cardSettingsRows.js, that the
template draws twice, so no row is written out by hand and each checkbox
reads the helper it always read. The tests that looked for a row's class in
the template look in the table now; tests/cardSettingsCoverage.test.cjs
derives each layout's default order from the templates and pins the popup's
shape; tests/cardFieldOrderLayout.test.cjs pins the arithmetic and its
negatives. No new translation keys: the heading and arrow keys already
existed in every locale.
Thanks to xet7 !
GET /api/boards/:boardId/boardViewSettings answers which entries of the
Board View menu a board offers, which one it opens in, separately for a
public and a private board, and the menu order - in the normalised shape the
menu renders with: every view once with both showOnPublic and showOnPrivate
explicit, the two defaults resolved (missing or unknown reads as Swimlanes),
boardViewOrder made whole, and `keys` listing the known views. Board access.
PUT /api/boards/:boardId/boardViewSettings takes any subset of
boardViewSettings, defaultPublicBoardView, defaultPrivateBoardView and
boardViewOrder, through the same pure modifiers the popup's clicks apply
(showBoardViewModifier, defaultBoardViewModifier, normalizeBoardViewOrder),
now composed by boardViewSettingsRequest() in models/lib/boardViewSettings.js:
a default is always shown on its side, hiding a side's current default is a
400 (set another default first - or in the same request, since defaults are
applied before the show flags), an unknown view key anywhere in the body is a
400 and nothing of that request is written, and the order is normalised so the
menu lists every view exactly once. Board admin (or site admin), the same
check as cardFieldOrder. Both answer boardViewSettingsSnapshot().
The existing GET/PUT /api/boards/:boardId/cardSettings routes get the JSDoc
@operation blocks the OpenAPI generator reads (get_board_card_settings,
update_board_card_settings), so the hand-written copy in
openapi/extra_paths.yml - which now duplicated the operationId - is removed.
public/api/wekan.yml and wekan.html are regenerated with the release
workflow's own commands: 158 operations. docs/API/REST-API.md documents both
endpoints with curl examples, and docs/Features/Board/Board-View-Settings.md
links to them.
tests/restApiNewFeatureRoutes.test.cjs pins the four routes to their method,
path, @operation and auth check, that the PUT writes only the helper's $set,
the snapshot's shape, the request helper's positive cases (setting a default
shows it, one request may move the default and hide the old one, the order is
normalised, the input board is not mutated) and negatives (unknown view key in
the order, the settings or a default; hiding a side's default; malformed
bodies; a partly-invalid body applies nothing), and that the generated and the
committed spec carry the four operations exactly once with the old
edit_board_card_settings gone.
Thanks to xet7 !
Each row of the Board View table now carries an up and a down arrow in front
of its name - real links, so the keyboard reaches them, titled with the
existing "Move up" / "Move down" keys of Card Settings' card field order -
and the Board View menu lists its entries in that order for everybody on the
board. Stored per board as boardViewOrder; normalizeBoardViewOrder() drops
unknown keys and duplicates and appends missing views in default order, and
moveBoardView() is a no-op for the first row up, the last row down and an
unknown view, so the menu always lists every view exactly once.
The menu itself is now rendered from the same table as the popup (one
`each boardViewMenuEntries` loop over models/lib/boardViewSettings.js)
instead of 25 static entries, keeping the per-view js-open-<view>-view class
each click handler listens for; the group separators are drawn only while
the order is the default one, since a custom order has no groups.
tests/boardViewMenu.test.cjs's order/icon/label/separator pins read that
table now, the same thing the template reads, and
tests/boardViewSettings.test.cjs pins the arrows, the schema field, the
setter and the normalize/move logic with positive and negative cases.
docs/Features/Board/Board-View-Settings.md describes it.
Thanks to xet7 !
Every feature of the recent releases that had a UI but no endpoint, on the
same server-side code the UI uses:
- DELETE /api/boards/:boardId/attachments/:attachmentId soft-deletes,
POST .../attachments/:attachmentId/restore restores, and
GET /api/boards/:boardId/attachments/deleted lists what is restorable -
all through the attachments.softDelete / attachments.restore methods the
card and the card history use, run as the request's user. No hard delete.
- GET /api/admin/problems (the Problems status overview plus the new-problem
count per stream), GET /api/admin/problems/:stream (one page, with
limit/skip/search) and POST /api/admin/problems/:stream/acknowledge,
through the admin-only eventLog* methods the Admin Panel pages call.
- GET /api/admin/oauth-providers, PUT /api/admin/oauth-providers/:providerKey
and PUT /api/admin/passwordless, through saveOauthProviderSettings,
savePasswordlessSettings and getOauthProviderConfigSources. A provider's
secret is reported only as { source, hasValue }, never its value.
- GET/PUT /api/boards/:boardId/cardFieldOrder, normalised with the same
applyCardFieldOrder() the card renders with.
- PUT /api/boards/:boardId/rules/:ruleId accepts `enabled` to pause and
resume a rule, and GET reports it.
The OpenAPI generator is fixed on the way: server/models/boards.js has had a
bare `catch {` since v11.67, the esprima parser cannot read that, and a parse
failure was silently skipped - so public/api/wekan.yml has shipped WITHOUT
the whole Boards API since then. It now downlevels `catch {` and
`for await (`, warns when a file cannot be parsed, and no longer emits an
empty sub-schema for a primitive array-element marker such as
`wipLimitGroups.$.listIds.$`, which made the spec unparseable YAML.
public/api/wekan.yml and wekan.html are regenerated with the release
workflow's own commands: 156 operations, up from 122.
tests/restApiNewFeatureRoutes.test.cjs pins every new route to its method,
path, @operation block and authentication check, that the OAuth endpoints
never mention a secret outside the input whitelist, the generator's two
fixes, that the generated and the committed spec carry the Boards API and the
new operations, and - as the negative sweep - that no route in models/ or
server/models/ lacks an authentication check.
Thanks to xet7 !
A new "Board View" entry at the top of Board Settings, above Swimlane, opens
a table like Card Settings: one row per entry of the Board View menu, in the
menu's order, with the columns Default on Public Board, Show on Public Board,
Default on Private Board, Show on Private Board and Description. The Default
columns are radio groups drawn as checkboxes (one default per side, and
setting one also shows it; the default's Show box cannot be un-ticked), and
the two public columns are not rendered when Admin Panel / Settings /
Visibility hides public boards.
The Board View menu lists only the views ticked for the board's current
visibility, and Utils.boardView() resolves the stored choice through the
board, falling back to that side's default, so nobody is left on a hidden
view. Stored per board as boardViewSettings, defaultPublicBoardView and
defaultPrivateBoardView; the decisions are the pure module
models/lib/boardViewSettings.js, applied by the Board setters
setBoardViewShown and setDefaultBoardView, guarded by the existing
board-admin allow rule. The schema fields, setters and popup template were
swept into 148f8a2aa by the Card Settings commit made from the same checkout;
this commit carries the rest.
Four new column-header keys, translated in every locale (low confidence for
the languages without a WeKan translator: Cherokee, Inuktitut, Klingon,
Volapük, Wolaytta, Bambara, Ewe, Fulah, Nahuatl and the other small ones).
docs/Features/Board/Board-View-Settings.md describes the design; tests/
boardViewSettings.test.cjs pins it, and boardSettingsSwimlaneListCard's
hr/gate guards now anchor on the group's new first entry.
Thanks to xet7 !
Flowtime, Pomodoro, Stickers and Location shipped without an allows* board
toggle, so they rendered on every card and Card Settings had no way to hide
them. Dependencies, Vote, Planning Poker, Text Notes and the activity history
on the opened card had the same gap, as did the dependencies, stickers,
comment-count, vote and poker badges on the minicard.
Each now has a Boards field (default true, so an existing board keeps showing
what it showed), a setter, a REST card-setting key, a healed true-default in
the schema upgrade, a row in Board Settings / Card with its click handler,
and a gate in cardDetails.jade / minicard.jade. allowsActivities already
existed but gated nothing and its row was commented out; it is wired now.
The rows of the popup are in the order the fields appear on the opened card
(Mark complete, number, cover; then the reorderable sections through the
same orderedCardFieldSections source the card renders from, so a board's own
order applies to both; then checklists ... comments, activities), with the
minicard-only rows beside the card row they belong with. No new i18n keys:
every row reuses the field's existing name.
tests/cardSettingsCoverage.test.cjs derives the card's order from the
template and pins the popup to it, checks every gate has a row and every new
row is read, and that none of the four sections is unconditional.
Thanks to rmb82 and xet7 !
Fixes#6688.
Fills the `attachment-soft-delete-pop` placeholder in 40 locale files
(ace, af, af_ZA, ak, am, an, ar, ar-DZ, ar-EG, ary, as, ast-ES, ay, az,
az-AZ, az-LA, ba, be, bg, bho, bi, bm, bn, bo, br, bs, bua, ca,
ca@valencia, ca_ES, chr, ckb, cmn, co, cs, cs-CZ, csb, cv, cy, cy-GB),
reusing each file's existing "attachments", "restore", "card" and
"history" vocabulary.
Low confidence: Acehnese, Akan, Aymara, Bislama, Bambara, Tibetan,
Buryat, Cherokee, Kashubian and Chuvash were written from dictionaries
and the locale's existing strings; a speaker's correction on Transifex
will replace them.
Thanks to xet7 !
Fills the attachment-soft-delete-pop placeholder in 39 locale files
(lt, lv, mai, mg, mi, mk, ml, mn, mr, ms, ms-MY, mt, my, nah, nap, nb,
nd, ne, nl, nl-NL, nso, ny, oc, om, or_IN, pa, pap, pl, pl-PL, ps, pt,
pt-BR, pt-PT, pt_PT, qu, rm, rn, ro, ro-RO), reusing each file's
existing words for attachment, card, file, restore and history.
Low confidence: mai, mg, mi, nah, nap, nd, nso, ny, om, or_IN, pap, qu,
rm and rn were written from dictionaries and the locale's existing
vocabulary; a native speaker should review them on Transifex.
Thanks to xet7 !
Fills the attachment-soft-delete-pop placeholder in the 34 locale files
uk-UA, uk, ur, uz-AR, uz-LA, uz-UZ, uz, ve-CC, ve-PP, ve, vi-VN, vi,
vl-SS, vo, wa-RR, wa, wal, wo, wuu-Hans, xh, yi, yo, yue_CN, zgh,
zh-CN, zh-GB, zh-HK, zh-Hans, zh-Hant, zh-TW, zh, zh_SG, zu-ZA and zu,
reusing each file's existing words for attachment, card, edit, restore
and history.
Low confidence: Venetian (ve-CC), Veps (ve-PP), Venda (ve), Volapük (vo),
Walloon (wa), Wolaytta (wal), Wolof (wo) and Tamazight (zgh, written in
Latin script like the file's other recent strings). uz-AR is written in
Latin Uzbek because the whole file is, matching its existing test.
Thanks to xet7 !
Fills the "attachment-soft-delete-pop" English placeholder in the locales
ru-UA, ru, ru_RU, rup, rw, sah, sc, scn, sd, se, si, sk, sl, sl_SI, sm, sn,
so, sq, sr, ss, st, sv, sw, szl, ta, te-IN, tg, th, ti, tig, tk_TM, tl, tlh,
tn, to, tpi, tr, ts, tt and ug, reusing each file's existing words for
attachment, card, history and restore.
Low confidence: rup, sah, se, sm, sn, ss, st, ti, tig, tlh, tn, to, tpi and
ts were written from dictionaries and the locale's existing vocabulary and
should be corrected by a speaker.
Thanks to xet7 !
The new key attachment-soft-delete-pop, added as an English placeholder in
5a09dca40, is now translated in these 39 locale files (gu-IN, gv, ha, haw,
he-IL, he, hi-IN, hi, hr, hsb, ht, hu, hy, id, ig, is, it, iu, ja-HI, ja-JP,
ja, jv, ka, kk, kl, km, km_KH, kn, ko-KR, ko, kok, ks, ku, kw, ky, la, lb,
lg, lld), reusing each file's existing words for attachment, card, history
and restore.
Low confidence, written from dictionaries and the file's own vocabulary:
Manx (gv), Hawaiian (haw), Inuktitut (iu), Greenlandic (kl), Kashmiri (ks),
Cornish (kw), Luganda (lg), Ladin (lld) and Upper Sorbian (hsb).
Thanks to xet7 !
Fills the attachment-soft-delete-pop placeholder in the da, de (+ de-AT,
de-CH, de_DE), dz, ee, el (+ el-GR), eo, es (+ es-AR, es-CL, es-CO, es-LA,
es-MX, es-PE, es-PY, es_CO), et-EE, eu, fa (+ fa-IR), ff, fi, fj, fo,
fr (+ fr-BE, fr-CA, fr-CH, fr-FR), fur, fy (+ fy-NL), ga, gd, gl (+ gl-ES)
and gn locales, reusing each file's existing card / attachment / history /
restore vocabulary.
Low confidence: dz, ee, ff, fj, gn (written from the locale's existing
terms and dictionaries; a native speaker should review), and to a lesser
degree fur, gd and fo.
Thanks to xet7 !
Delete on an attachment used to remove the document and its file at once.
It is now the 'attachments.softDelete' method (History.md section 12): the
document gets deletedAt/deletedBy/deleteBatchId with the same helpers lists
use, the file is kept, and the card's cover is unset if this was it. Every
card-facing read - the opened card's gallery and "Attachments (N)" count,
the minicard paperclip badge, the slideshow, the cover, the board-background
picker, My Attachments, the API list endpoints and the exporters - filters
to live attachments with liveAttachments(); the publications keep sending
the deleted ones so the card history can reach them.
The card history records who deleted it and when, with the filename in the
row. Restore - the table's selection + Restore, or the row's own Restore
button, both through changeHistory.restore and applyAttachmentContent -
clears the mark, so the card, its count and the minicard badge include the
attachment again; the cover is never re-set. An attachment row previews
with the existing attachmentViewer slideshow and downloads with the same
link the gallery draws, and never offers cover or background. Uploads and
renames are recorded through the existing history hooks.
There is no per-attachment hard delete any more: api.attachment.delete,
DELETE /api/attachment/delete/:id and removeBoardBackground soft-delete,
permanentlyDeleteAttachmentFromFilesReport and the Files report's delete
button are gone, Attachments.allow remove and onBeforeRemove refuse every
client remove and log the attempt under Admin Panel / Problems. The one
hard delete is Admin Panel / Problems / Delete enabled, board archived,
board deleted from the archive: boardRemover now removes every attachment
of the board, live and soft-deleted, with its file.
One new i18n key, attachment-soft-delete-pop, replaces the "permanent, no
undo" confirmation text; it is inserted in English into every locale at
the same position for translation.
Thanks to xet7 !
Opens the next Upcoming section above v11.70 with the entry for
037975a9d, under a "The release workflow" group: what the v11.70 run's
Windows jobs said, why the Visual Studio 2026 runner image broke Meteor's
node-gyp 10.2.0 pin, and what bump-bundle-node-gyp.mjs does about it. Also
records which of that run's other failures were the runner's (snapcraft LXD
timeouts, the Launchpad riscv64 job cap) rather than the repository's.
Thanks to xet7 !
build-win64 and build-win-arm64 both failed the v11.70 release run
(GitHub Actions run 93730167566) in "Rebuild native modules for Windows",
inside `npm install` in bundle/programs/server, while argon2's install
script compiled it:
gyp info using node-gyp@10.2.0
gyp ERR! find VS unknown version "undefined" found at
"C:\Program Files\Microsoft Visual Studio\18\Enterprise"
gyp ERR! find VS could not find a version of Visual Studio 2017 or newer to use
gyp ERR! stack Error: Could not find any Visual Studio installation to use
Why. On 2026-09-07 GitHub's `windows-latest` became the
`windows-2025-vs2026` image (runner image 20260907.229.1), which carries
Visual Studio 18 (2026) and no longer 17 (2022). The node-gyp that compiles
is not one this repository installs: Meteor's bundler writes
programs/server/package.json with `"node-gyp"` pinned to the copy inside
the Meteor tool - 10.2.0 in Meteor 3.5.2 - and that version knows the major
versions 15, 16 and 17 and nothing newer. The shrinkwrap beside it does not
list node-gyp at all, so the pin is the only thing `npm install` consults.
argon2 always compiles on Windows: the amd64 bundle's win32-x64 prebuild is
there, but node-gyp-build's `node-gyp-build-test` probe runs through the
Linux-made `.bin/` shims, which are not `.cmd` files, so the probe fails and
it falls through to `node-gyp rebuild`. With Visual Studio 2022 that worked;
with 2026 and node-gyp 10 it cannot.
What changed. releases/bump-bundle-node-gyp.mjs raises an exact node-gyp pin
below 13.0.2 in a built bundle's programs/server/package.json (12.1.0 added
Visual Studio 2026 support; 13.0.1/13.0.2 fixed its version detection,
nodejs/node-gyp#3338; 13.0.2's engines accept the Node.js 24 the runners
use). It runs ONCE, in build-amd64's "Install server npm modules" step
BEFORE the first `npm install`, because every other architecture - the
Windows legs, arm64, the extra arches - reinstalls programs/server from that
same package.json, so one rewrite travels to all of them. A pin already at
or above the minimum, a range, or a bundle without a pin is left as it is,
so a Meteor release that ships a newer node-gyp keeps its own.
releases/build-release-bundle.sh does the same before its install, so a
local release bundle is what a release ships.
tests/bumpBundleNodeGyp.test.cjs pins the script's decisions (bump, keep,
no pin, dry run, unreadable, read-only), that the minimum is a node-gyp
with the Visual Studio 2026 fix, that release-all.yml runs it in the amd64
install step before `npm install` and nowhere else, and (negative) that no
workflow leg hard-codes node-gyp 10.2.0 or a GYP_MSVS_VERSION workaround.
tests/buildScriptParity.test.cjs lists the script with its bundle-time
siblings.
Not fixable from here, in the same run: the three amd64 snap jobs died in
snapcraft's LXD base-instance creation (`apt-get install -y snapd` timed
out after 600 s; the arm64 twins passed), and snap-launchpad riscv64 was
still building on Launchpad when the job cap cancelled it.
Thanks to xet7 !
History.md gains section 12 and closes the section 11 question about restoring
a removed attachment: delete on a card is a soft delete that keeps the file and
unsets the cover, the card, its count and the minicard badge hide it, the card
history shows who deleted it and restores it with the same preview and download
controls as the card but never cover or background, no per-attachment hard
delete exists anywhere, and the one hard delete is Admin Panel / Problems /
Delete enabled, board archived, board deleted from the archive.
Thanks to xet7 !
The bump job of release-all.yml (.tools/wekan13, run 93672173482)
regenerates public/api/wekan.yml with openapi/generate_openapi.py and then
renders it with @redocly/cli, which stopped the release with
"Error: bad indentation of a mapping entry in public/api/wekan.yml
(1232:2)". A @param whose description continues on the next JSDoc lines -
models/exportCharts.js's chartKey, "one of dashboard, burndown, ...
controlChart, ..." - was emitted under `description: |` with only its
FIRST line indented; the continuation lines landed at column 1, which is
no longer inside the block scalar, so the whole spec failed to parse.
print_openapi_param now indents every line of the description.
The same job warned "unknown type object / allowed values: string,
number, boolean, integer, array, file" four times for the rules API's
trigger/action params. OpenAPI 2.0 has no `object` for a path/query/form
parameter; those are now emitted as `type: string` / `format: json`
(the REST API takes them as JSON in a string), and `object` no longer
warns.
Reproduced locally (PyYAML: "expected <block end>, but found '<scalar>'
... line 1232, column 2"); after the fix the spec parses and
`npx @redocly/cli build-docs` - the exact step that failed - renders it.
tests/openapiParamMultiline.test.cjs pins the emitter and, where python3
with PyYAML is available (it is in CI), parses the regenerated spec.
Thanks to xet7 !
Fills the 17 new OAuth-provider / passwordless strings in the last 53
locale files: Akan, Amharic, Aymara, Bislama, Bambara, Buryat, Cherokee,
Ewe, Fulah, Fijian, Guarani, Hausa, Hawaiian, Haitian Creole, Igbo,
Inuktitut, Greenlandic, Cornish, Luganda, Malagasy, Maori, Nahuatl,
Northern Ndebele, Northern Sotho, Chichewa, Oromo, Papiamento, Quechua,
Kirundi, Kinyarwanda, Samoan, Shona, Somali, Swati, Southern Sotho,
Swahili, Tigrinya, Tigre, Tswana, Tongan, Tok Pisin, Tsonga, Venda,
Venetian, Veps, Flemish, Wolaytta, Wolof, Xhosa, Yoruba, Zulu and
Klingon. With this every non-English locale has all 24 keys translated
and `fill-translations.mjs --missing` reports no language with
untranslated strings.
The Venetian and Veps files were seeded with Spanish and Finnish and the
Klingon file with German; the new strings are written in the language the
locale tag names. Low confidence: the Cherokee, Inuktitut, Nahuatl,
Aymara, Quechua, Buryat, Veps, Wolaytta, Tigre, Fulah and Klingon strings
were written from dictionaries and the files' own existing vocabulary and
would benefit from a native speaker's review.
Thanks to xet7 !
Fills the 17 new OAuth-provider / passwordless strings in 29 more locale
files: Assamese, Bhojpuri, Tibetan, Dzongkha, Gujarati, Kannada, Konkani,
Kashmiri, Khmer, Malayalam, Maithili, Marathi, Burmese, Nepali, Odia,
Punjabi, Pashto, Sindhi, Sinhala, Tamil, Telugu, Urdu, Central Kurdish,
Kurmanji Kurdish, Cantonese, Javanese, Acehnese and Tagalog. The provider
names stay in Latin script, as those files already write Google and
GitHub, and %s and the environment-variable names are copied verbatim.
Low confidence: the Tibetan, Dzongkha, Kashmiri, Konkani, Maithili,
Bhojpuri and Acehnese strings were written from dictionaries and the
files' own existing vocabulary and would benefit from a native speaker's
review.
Thanks to xet7 !
Fills the 17 new OAuth-provider / passwordless strings in 62 more locale
files: Afrikaans, Aragonese, Asturian, Azerbaijani, Bashkir, Belarusian,
Bosnian, Breton, Corsican, Kashubian, Chuvash, Welsh, Esperanto, Faroese,
Friulian, Frisian, Irish, Scottish Gaelic, Manx, Upper Sorbian, Armenian,
Icelandic, Georgian, Kazakh, Kyrgyz, Latin, Luxembourgish, Ladin,
Macedonian, Mongolian, Maltese, Neapolitan, Occitan, Romansh, Aromanian,
Sakha, Sardinian, Sicilian, Northern Sami, Albanian, Silesian, Tajik,
Turkmen, Tatar, Uyghur, Uzbek, Volapük, Walloon, Yiddish and Standard
Moroccan Tamazight, plus their regional variants and the Algerian,
Egyptian and Moroccan Arabic files, which take the Arabic strings.
Macedonian and Mongolian were seeded with Bulgarian and Russian vocabulary;
the new strings are written in the language the locale tag names, as the
translation policy requires. Low confidence: Ladin, Aromanian, Kashubian,
Manx, Sakha, Chuvash, Bashkir, Volapük, Walloon and the Tifinagh Tamazight
strings were written from dictionaries and the files' own existing
vocabulary and would benefit from a native speaker's review.
Thanks to xet7 !
Meteor's own accounts packages - accounts-google, accounts-github,
accounts-facebook, accounts-twitter, accounts-meteor-developer,
accounts-weibo, accounts-meetup and accounts-passwordless - are added, so
every way to log in that Meteor's accounts system offers is available.
models/lib/oauthProviders.js is the pure catalog of the seven providers
(env var names, ServiceConfiguration id field, login method, icon, label
key) with the decisions built on it: OAUTH_<PROVIDER>_ENABLED plus id and
secret (each also read from a <NAME>_FILE Docker secret), the Admin Panel
override winning over the env var, OAUTH_PROVIDERS_LOGIN_STYLE,
OAUTH_PROVIDERS_MERGE_EXISTING_USERS and PASSWORDLESS_ENABLED.
server/lib/oauthProviders.js writes ServiceConfiguration for every enabled
provider at startup and on demand (reconfigureOauthProviders, called by the
Admin Panel after a save) and removes it for a disabled one, so switching a
provider off takes effect without a restart. A first login through a
provider becomes a WeKan user the way OIDC does, fail-closed: an existing
account of another login method is only linked when merging is on and the
provider verified the address, otherwise the login is refused and the
attempt recorded on the new oauth.account-conflict canary for Admin Panel
-> Problems. Passwordless is gated on both the token-request method and
the login attempt while it is off.
getAuthenticationsEnabled reports each enabled provider key and
passwordless, and the login form shows one button per provider and a
two-step e-mailed-code form under the SAML button, with errors in the same
region as the password form. No credential ever reaches the client.
tests/oauthProviders.test.cjs covers the catalog, the env/_FILE/admin
resolution, the enabled and takeover decisions, the ServiceConfiguration
upsert/remove, the canary, the login form and the no-secret-on-the-client
negative checks.
Thanks to xet7 !
Fills the 17 translatable strings of the new OAuth-provider / passwordless
keys in the 45 most-used languages and their 43 regional variants: German,
French, Spanish, Italian, Portuguese (European and Brazilian), Dutch,
Polish, Russian, Ukrainian, Czech, Slovak, Finnish, Swedish, Danish,
Norwegian Bokmål, Hungarian, Romanian, Bulgarian, Greek, Turkish, Arabic,
Hebrew, Persian, Hindi, Bengali, Indonesian, Malay, Vietnamese, Thai,
Japanese, Korean, Chinese (Simplified and Traditional), Catalan, Galician,
Basque, Estonian, Lithuanian, Latvian, Slovenian, Croatian and Serbian.
The provider names Google, GitHub, Facebook, X (Twitter), Meteor Developer,
Weibo and Meetup stay in Latin script, as every locale file already writes
Google and GitHub; %s and the MAIL_URL, PASSWORDLESS_ENABLED and
OAUTH_*_ENABLED names are copied verbatim. Written with the fill tool,
which only ever writes into English placeholders.
Thanks to xet7 !
OAUTH_GOOGLE_*, OAUTH_GITHUB_*, OAUTH_FACEBOOK_*, OAUTH_TWITTER_*,
OAUTH_METEOR_DEVELOPER_*, OAUTH_WEIBO_*, OAUTH_MEETUP_*,
OAUTH_PROVIDERS_LOGIN_STYLE, OAUTH_PROVIDERS_MERGE_EXISTING_USERS and
PASSWORDLESS_ENABLED are now documented, commented out or defaulted, in
every place the OAUTH2_* and SAML_* settings already are: docker-compose.yml
and its FerretDB v1 / v2 and MongoDB variants, the Dockerfiles' ENV block,
start-wekan.sh, start-wekan.bat, the Snap config (keys list plus
DESCRIPTION_/DEFAULT_/KEY_ triples) and wekan-help, the Sandstorm package
definition, the stacksmith Docker-secrets reader and secrets/README.md.
The comments name the callback URL to register at each provider,
<ROOT_URL>/_oauth/<service>, and say that Admin Panel / People / Login
overrides the environment.
New docs pages docs/Features/Login/OAuth-Providers.md and Passwordless.md,
linked from the docs index. tests/oauthProvidersPlatformEnv.test.cjs pins
that every variable is present on every platform and that the docs exist
and are linked.
Thanks to xet7 !
Admin Panel / People / Login gets a section for Meteor's own accounts-*
login services (Google, GitHub, Facebook, X/Twitter, Meteor Developer, Weibo,
Meetup) and for passwordless login, built the same way as the LDAP section:
every OAUTH_<PROVIDER>_ENABLED / _CLIENT_ID / _SECRET env var, the shared
OAUTH_PROVIDERS_LOGIN_STYLE and OAUTH_PROVIDERS_MERGE_EXISTING_USERS, and
PASSWORDLESS_ENABLED can be set there, a value set in the Admin Panel wins
over the env var, and a badge beside each field names the source in effect.
The secret is stored in Settings.oauthProviders.<key>.secret and, like the
LDAP bind password, is never published: only the boolean secretSet is, an
empty secret submission leaves the stored one untouched, and the sources
method reports it through hasConfigValue() only. saveOauthProviderSettings
validates the provider key against the catalog and both save methods call
reconfigureOauthProviders() so a change takes effect without a restart.
Tests: tests/oauthProvidersAdminOverride.test.cjs, and the whole-tree secret
sweep in tests/ldapAdminOverrideSecurity.test.cjs now also matches
hyphenated sub-document keys.
Thanks to xet7 !
Adds 24 keys after "ldap-test-connection-error" in en.i18n.json and every
other locale file, with the English source as the value for now: the Admin
Panel section for the Google, GitHub, Facebook, X (Twitter), Meteor
Developer, Weibo and Meetup OAuth providers, the "Sign in with %s" button,
and the passwordless one-time email code login. The seven provider names
are proper nouns, so fill-translations.mjs now treats them as invariant
values that legitimately stay identical in Latin-script locales; the
translations of the other strings follow in separate commits.
Thanks to xet7 !
server/models/collectionBootstrap.js already owned this collection's index
(the unique cardCommentId one); 03ffb56a5 added a second module for the
same collection. One place per collection: the cardId and boardId indexes
now sit beside the existing one there, and the separate module is gone.
tests/cardCommentReactionsIndexes.test.cjs pins that arrangement.
Thanks to xet7 !
The reported crash series (.tools/crash) was invisible from inside WeKan:
MongoDB aborting on every checkpoint, restarting, aborting again, with
every query in between slow - and the admin found it in the container log.
Admin Panel / Problems / Database problems now gets a row for each thing
WeKan can measure from its side of the socket, from a probe that runs 30 s
after startup and every five minutes (server/lib/databaseHealth.js, the
pure decisions in models/lib/databaseHealth.js):
- db.restart: serverStatus.uptime went down while WeKan kept running - the
database process restarted; points at the fatal-assertion/fsync cause and
the storage page.
- db.network-filesystem: getCmdLineOpts' dbPath, when it is a directory
this process can see (snap, embedded database, shared volume), is on a
CIFS/SMB, NFS or FUSE filesystem (fs.statfs f_type).
- db.slow-storage: serverStatus.opLatencies reads averaged over 100 ms
across the interval, on a real number of reads - the storage latency
behind the "Slow query" lines.
- db.disk-space: dbStats fsUsedSize/fsTotalSize below 5% or 512 MiB free -
the real "no space left on device", before it happens.
- db.index-created: the one remediation WeKan can do itself. ensureIndex
(server/lib/mongoStartup.js) now reports an index it created on a
collection that already held documents - until then every query on it
was a collection scan - as found and fixed; a new, empty collection
getting its indexes at first start stays silent.
All rows go through the existing `database` stream (recordDatabaseHealth in
server/lib/databaseProblems.js: same shape, same per-minute quieting per
type), so they land on the same page as what the database itself says.
FerretDB answers only some of these commands; each step is independent and
what it cannot answer is skipped. Nothing here can throw into startup or
sits on a request path.
tests/databaseHealth.test.cjs drives every decision (including the
reported case: 519 MB used, 10 GiB free is NOT a space problem) and pins
the wiring.
Thanks to xet7 !
From a reported MongoDB crash series (.tools/crash: WeKan and MongoDB in one
Kubernetes pod, the database volume on an SMB/DFS share):
- The crash itself is WiredTiger's checkpoint fsync() returning ENOSPC
("No space left on device" with 519 MB used and 10 GiB free) on the
network share, followed by a fatal assertion and abort - every checkpoint,
so a restart loop. That is the storage, not WeKan: MongoDB requires a
local filesystem with real fsync semantics under its data directory.
docs/Databases/MongoDB/Storage-Requirements.md now says so, shows what
the log looks like when it is not, and what to do (local block volume;
attachments may still live on a share; MONGO_URL over TCP is fine).
- The WeKan-side finding in the same logs: card_comment_reactions had no
index at all, and every board open queried it by `cardId: { $in: [...] }`
and by `boardId` as a full collection scan - 3,397 COLLSCANs of that one
collection in the last crash log, up to 1.6 s each, the bulk of its
"Slow query" lines. server/models/cardCommentReactions.js now ensures
indexes on cardId, boardId and cardCommentId at startup, like every other
per-card collection.
tests/cardCommentReactionsIndexes.test.cjs pins both.
Thanks to xet7 !
The section had grown by appending a subsection per batch of work - five
"adds ...", two "fixes the following bug(s)", three developer-tooling and
two "closes the following already-fixed issue" subsections in
chronological order. They are now one subsection per kind, in the
documented order: CodeQL security fixes, new features, bug fixes,
developer tooling, documentation, closed already-fixed issues,
translations - the same-kind subsections merged, the one-off "adds a
GDPR-friendlier alternative" / "adds Sign in with Apple" / "adds REST API
improvements" subsections folded into the features list as topic groups,
and every merged subsection fully grouped.
47 commits since the v11.68 release had no entry at all (the CodeQL
negative-test rewrite, the Jade build fixes, the document-preview 415
fixes, the "Remove all labels" rule action, checklist automatic reset,
in-place rule editing, card-to-new-board, the Bigboard view registration,
a dozen regression-test additions and guard updates, two docs pages, two
TODO Later updates and nine translation/i18n-key commits); each is linked
now under its kind.
Thanks to xet7 !
The three alerts under .tools/wekansec19 point at tests, not application
code: the negative tests added with 9cbf67ba7 (which fixed the real
occurrences of these three patterns) reproduce each OLD bug so they can
prove it is gone - and did so with the exact construct CodeQL flags, so
the alerts stayed open on the test lines:
- tests/cardUrlAutolink.test.cjs:200 (js/incomplete-sanitization, #536):
the ']'-only escaping is now reproduced with split/join instead of a
']'-only regex replace.
- tests/oauthLogoutUrl.test.cjs:101
(js/incomplete-url-substring-sanitization, #535): the naive `includes`
check now assembles the hostname at run time instead of a literal.
- tests/boardCreationAdminOnly.test.cjs:129 (js/identity-replacement,
#534): the "replace a space with a space" no-op now builds its RegExp at
run time instead of the literal /\ /g.
Each test still asserts the same old-vs-new difference; only the way the
old behaviour is written changed. No application code was affected, so no
security-log entry applies.
Thanks to GitHub CodeQL and xet7 !
Reported directly: Admin Panel / People / Roles threw from its status
table's column value functions, which call TAPi18n.__() in
client/components/settings/peopleBody.js - a file that never imported
TAPi18n (a named export of /imports/i18n, not a global). Sweeping the tree
for the same shape found it in two more files that would fail the same way
the moment their TAPi18n call ran: client/components/settings/
lockedUsersBody.js (the unlock confirmation) and client/components/boards/
multiboardCalendarView.js (its calendar locale and labels).
tests/clientSingletonImports.test.cjs now sweeps for TAPi18n too, beside
Utils and ReactiveCache.
Thanks to xet7 !
Reported directly, with screenshots: on Board Settings / Rules, clicking
"Workflow view" in the page sidebar changed the button's label to "List
view" but the page kept showing the "Add trigger" tab - the workflow
builder never appeared.
rulesMain.jade renders +rulesWorkflow only while its rulesCurrentTab
ReactiveVar is 'rulesList'. The toggle lives in rulesControls, a separate
template in the page sidebar with no handle on the rulesMain instance, so
it only flips Session 'rulesViewMode'; from the Add trigger / Add action /
rule details tabs that changed nothing visible. rulesMain now owns an
autorun that brings the page back to the list tab whenever the workflow
view is selected - the one place the tab state can be changed from.
tests/rulesWorkflowViewToggle.test.cjs pins it.
Thanks to xet7 !
Reported directly, with a LibreOffice screenshot: the Frappe Gantt view's
Excel export showed Start/Due/End as ISO text ("2026-09-23T09:00:00.000Z").
ExporterChartExcel wrote cell.toISOString() into the cell. A date is now a
real date cell with a date number format (yyyy-mm-dd hh:mm), so the
spreadsheet shows it in its own date format, sorts it as a date and can do
arithmetic on it; the "-" placeholder for an unset date stays text. Every
chart export (Gantt, Time, the report charts) shares this exporter.
The follow-up ask - every other Excel export too:
- The board and card Excel exports draw the shared card document
(models/lib/cardDocument.js), whose meta pairs were pre-formatted text
(fmtDate), so Created/Received/Start/Due/End/Last activity were text
there as well. A date pair now carries the raw Date as a third element
([label, text, Date]); renderCardDocumentExcel writes that as a date cell
and the PDF keeps printing the text. ExporterExcelBoard's own
Created/Modified lines get the same treatment.
- The legacy whole-board Excel export (ExporterExcel.js) already wrote Date
values into numFmt columns; nothing to change, pinned as such.
tests/chartExcelDateCells.test.cjs drives the chart row-writing branch
against a stand-in worksheet and pins the other exporters' shapes;
tests/pdfExport.test.cjs updated for add()'s third argument.
Thanks to xet7 !
Reported directly: in the Frappe Gantt view's PDF export a row's text was
not on one line. ExporterChartPDF wrote every header and data row as ONE
text line - "title | start | due | end" - with no width limit, so a
long card title pushed the dates off the page edge in the Unicode PDF and
past the line in the base-font fallback, and nothing lined up from row to
row.
New models/lib/pdfDocument.js tableRow(): a row with fixed column widths
(the name column twice the others), a cell that does not fit clipped with
an ellipsis rather than wrapped, so a row is always exactly one line.
buildUnicodePdf draws it as measured cells (PDFKit width + ellipsis); the
base-font fallback gets the same row as padded monospaced runs within the
text width. ExporterChartPDF uses it for the header (grey bar, bold) and
every row of every chart export - Gantt, Time and the report charts share
this exporter.
tests/chartPdfTableRows.test.cjs pins the one-line/aligned-columns/clipping
behaviour and that the exporter no longer joins rows into unbounded text.
Thanks to xet7 !
Fill the five gantt-view-* keys (hour, quarter day, half day, year and the
"Mode" dropdown placeholder) in the last translation batch, uk-UA through zu,
using each locale's existing day/week/month/hour vocabulary as reference.
Low confidence: Veps (ve-PP), Venda (ve), Volapük (vo), Waray (wa-RR),
Walloon (wa), Wolaytta (wal), Wolof (wo), Tamazight (zgh, kept in the Latin
Tamazight the file already uses) and Yoruba (yo). uz-AR keeps the Latin-script
Uzbek its file and test already pin.
Thanks to xet7 !
Fill the five gantt-view-* placeholders (hour, quarter day, half day, year
and the view-mode dropdown placeholder) in 40 locale files, written from
each language's existing day/week/month/hours strings and its calendar
vocabulary. "Mode" is rendered as "view mode" in every language so the
value differs from the English placeholder.
Low confidence: rup (Aromanian), sah (Yakut), se (Northern Sami), sm
(Samoan), sn (Shona), ss (Swati), tig (Tigre), tlh (Klingon), to (Tongan),
tpi (Tok Pisin), ts (Tsonga), and the Bantu quarter-day phrases (rw, st,
tn, ts, ss).
Thanks to xet7 !
Fill the five gantt-view-* placeholders (Hour, Quarter Day, Half Day, Year,
Mode) that were added in English for every locale, using each language's
existing day/week/month/hours terms as the reference. "Mode" is rendered as
"view mode" in each language, since the dropdown placeholder reads "view mode".
Low confidence: Manx (gv), Hausa (ha), Hawaiian (haw), Upper Sorbian (hsb),
Igbo (ig), Inuktitut (iu), Greenlandic (kl), Kashmiri (ks), Cornish (kw),
Luganda (lg) and Ladin (lld) - especially the "quarter day" phrase, which
none of these files had an existing pattern for.
Thanks to xet7 !
Fill the five gantt-view-* keys (Hour, Quarter Day, Half Day, Year and the
"Mode" dropdown placeholder) in 40 locale files: da, de, de-AT, de-CH, de_DE,
dz, ee, el, el-GR, eo, es and its 8 regional variants, et-EE, eu, fa, fa-IR,
ff, fi, fj, fo, fr and its 4 regional variants, fur, fy, fy-NL, ga, gd, gl,
gl-ES and gn. Only English placeholders were written; existing translations
are untouched.
Low confidence: dz (Dzongkha), ee (Ewe), ff (Fula), fj (Fijian) and gn
(Guarani) were written from dictionary vocabulary and each file's existing
day/week/month terms; a native speaker may want to correct them.
Thanks to xet7 !
Fill the five gantt-view-* keys (Hour, Quarter Day, Half Day, Year and the
"Mode" dropdown placeholder) directly, from each locale's existing day, week,
month and hours strings and its calendar vocabulary. Applied through
fill-translations.mjs --apply, so only the English placeholders were written.
"Mode" is rendered as "view mode" in each language so it differs from English.
Low confidence: mai, mg, mi, my, nah, nap, nd, nso, ny, om, qu, rm, rn (words
looked up rather than known), and ps/or_IN spelling. A native speaker can
correct them on Transifex; that correction wins over these fills.
Thanks to xet7 !
Fill the five gantt-view-* keys (Hour, Quarter Day, Half Day, Year and the
"Mode" dropdown placeholder) in the 40 locale files ace, af, af_ZA, ak, am,
an, ar-DZ, ar-EG, ar, ary, as, ast-ES, ay, az-AZ, az-LA, az, ba, be, bg, bho,
bi, bm, bn, bo, br, bs, bua, ca, ca@valencia, ca_ES, chr, ckb, cmn, co,
cs-CZ, cs, csb, cv, cy-GB and cy, using each file's existing day/week/month
vocabulary as the reference. Catalan "Mode" is identical to English, so it
is written as "Mode de vista".
Low confidence: ace, ak, ay, bi, bm, bo, bua, chr, csb and cv.
Thanks to xet7 !
Reported directly: the Frappe Gantt view (and the DHTMLX Gantt, WeKan Gantt,
Time and the ten report-chart views) each showed two untranslated
"Export to PDF" / "Export to Excel" links. They now share one translated
"Export" button that opens a new exportChartPopup - the same pop-over list
of formats the board/swimlane/list/card export popup uses, offering PDF
and Excel with the same icons and labels. The URL is built in exactly one
place, client/components/boards/charts/exportChart.js's chartExportUrl();
the five per-view copies of that helper (gantt.js, frappeGantt.js,
dhtmlxGantt.js, timeView.js, boardCharts.js) are gone. One delegated click
handler opens the popup with the view's data-chart-key as its data context.
The popup's title, exportChartPopup-title, is added to every locale from
that locale's existing "export" translation - no new words to translate.
Also from the same report: Frappe Gantt's own chrome was English in every
language. Its view-mode dropdown prints each mode's `name` and looks modes
up by it, so it now receives translated copies of Frappe's default modes
(GanttLib.VIEW_MODE) - Day/Week/Month from the existing keys, and four new
keys (gantt-view-hour, -quarter-day, -half-day, -year) added to every
locale as English placeholders to be filled next. Its hardcoded "Today"
button and "Mode" placeholder are rebuilt on every view change, so a
MutationObserver re-translates them (existing "today" key; new
gantt-view-mode), disconnected in onDestroyed.
tests/chartExportPopup.test.cjs pins all of it; boardViewMenu,
reportChartLibraries and timeViewReportAndExport updated from the old
per-view links to the shared button/builder.
Thanks to xet7 !
Reported directly: both Gantt board views showed English month names in
every language. Neither library reads WeKan's translations: Frappe Gantt
takes a `language` tag it hands to Intl.DateTimeFormat, and DHTMLX Gantt
takes a locale object and only bundles a fixed set (~40) of them,
defaulting to English.
New client/lib/ganttLocale.js (pure, unit-tested) feeds both:
- intlLocaleFor() maps WeKan's language tag to one Intl accepts - the
underscore tags ('ru_RU', 'ca_ES', 'zh_SG', ...) make Intl throw
RangeError, and an unknown tag falls back to its primary subtag, then
English, so nothing can throw inside a library's render loop. Every tag
under imports/i18n/data resolves (pinned by the test).
- intlDateNames() builds month_full/month_short/day_full/day_short from
Intl for any language, in dhtmlx's shape (weeks starting Sunday).
- dhtmlxLocaleFor() uses the locale dhtmlx bundles for the language when
there is one (it also translates dhtmlx's own labels), and otherwise
keeps the English labels with the Intl date names.
frappeGantt.js passes `language`; dhtmlxGantt.js calls
gantt.i18n.setLocale() on each reactive run before init/parse so a
language change takes effect. The Frappe view-mode dropdown's own
"Day/Week/Month/Year" labels are the library's and stay as they are.
Thanks to xet7 !
Reported directly: the Dashboard view showed nothing above its table, with
"Exception from Tracker afterFlush function: Error: There is no current
view" from client/components/boards/charts/boardCharts.js. The chart is
deliberately built inside Tracker.afterFlush so the <canvas> exists by
then, but that callback runs outside every Blaze view, where
Template.currentData() throws - and one such call (the dataset title) sat
inside it, aborting the whole chart build with nothing to retry it.
The data context is now read once in the autorun, before afterFlush, and
only the captured chartKey/titleKey are used inside the callback.
tests/boardChartsAfterFlushContext.test.cjs pins that no afterFlush body
in this file calls Template.currentData()/Template.instance().
Thanks to xet7 !
Reported directly, following the Flowtime "Add Interruption" fix: the
Timeline view's "Restore to this state" button was likewise an unthemed
default button. Searching every jade `button` for the same shape found two
more labelled action buttons from recent features with no theme class:
the List popup's "Sync now" (between a `.primary` Save and a `.negate`
Clear) and Admin Panel / Login's "Test LDAP Connection" (beside a
`.primary` Save). All three now carry `.primary`, like "Start Pomodoro".
Pagination arrows, sort headers, icon-only toggles and the vote/poker
buttons keep their own deliberate styling and were left alone.
tests/actionButtonsUseThemeClass.test.cjs pins the six labelled action
buttons (Flowtime start/interruption, Pomodoro start, and these three).
Thanks to xet7 !
Reported directly: on an opened card, "Add Interruption" rendered as an
unthemed default button next to "Start Pomodoro", which carries the
`.primary` theme class (as do "Start Flow" and every other primary action
button). The interruption button had no theme class at all. Added
`.primary`; tests/flowtimeSession.test.cjs now pins it.
Thanks to xet7 !
Reported directly: after adding a label to an opened card, clicking it in
the Labels popup no longer made it wider or applied it to the card. It
worked in the previous release.
The reorderable card detail sections (131514d61) are rendered by an `each`
over the board's stored section order. The plain `each
orderedCardFieldSections` form sets the data context of everything inside
it to the current item - the section NAME string ("labels", "dates", ...) -
so every section template, and every popup opened from one, received a
string where it expected the card. Popup.open uses the clicked element's
data context, so the Labels popup's `templateInstance.data` was "labels":
`card.toggleLabel` was undefined and the click handler returned silently,
`isLabelSelected ../_id` looked up `_id` on a string, and the section's own
`each labels` / `each stickers` / `each getLocations` rendered nothing. The
earlier fixes this session (global helpers, missing imports, the sortable
`stop` handler) each removed a real exception on this path but could not
restore the toggle, because the popup still had no card.
Switched the loop to `each section in orderedCardFieldSections`, the form
already used elsewhere in this file, which keeps `this` as the card and
exposes the item as `section`.
tests/cardFieldSectionsKeepCardContext.test.cjs pins the `in` form and that
every branch compares `section`; tests/cardFieldOrder.test.cjs updated to
the new loop text (its intent - the order-driven loop - is unchanged).
Thanks to xet7 !
Reported directly: clicking a label in the Labels popup no longer toggled
it onto the card (grow wider/apply on first click, shrink/remove on
second), with the browser console showing "card.board is not a function"
thrown from jQuery UI sortable's stop handler in
client/components/cards/labels.js (the label-reorder drag on
cardLabelsPopup).
jQuery UI's sortable widget runs its `stop` callback on mouseup whenever a
drag was registered, which ordinary mouse/trackpad clicks can trigger even
without an intentional drag - so this handler fires far more often than
"the user actually reordered labels." It resolved the card via
`Blaze.getData(this).board()`, where `this` is the sortable's root
`.edit-labels-pop-over` element; that does not reliably resolve back to a
real Card document with a callable `.board()`, so it threw. An uncaught
exception inside jQuery UI's own `_clear()` cleanup (which is what invokes
this `stop` callback) aborts the rest of that cleanup, consistent with the
toggle-on-click visuals getting stuck even though the click handler itself
runs independently.
The sibling `click .js-select-label` handler two lines below already had
the right fix for the same problem (added for linked-card labels): resolve
the board from the popup TEMPLATE's own data via `getCardLabelBoard(...)`,
never from `Blaze.getData` on a DOM node that may not carry the card
context the popup was actually opened with. Applied the same fix to the
`stop` handler.
tests/labelReorderStopHandler.test.cjs pins the fix and negatively checks
the old Blaze.getData(this) shape can't come back.
Verified against a real Meteor boot (`meteor run`) in-sandbox.
Thanks to xet7 !
Reported directly: clicking a newly created label did not enlarge it or
apply it to the card. The browser console showed "Exception in
Template.cardFlowtime canControlFlow" and the same for
Template.cardPomodoro canControlPomodoro - both call Utils.canModifyCard()
but never import Utils (a plain ES export from client/lib/utils.js, not a
Meteor global), so the helper threw a ReferenceError the moment either
template's reactive computation ran, which broke the surrounding card
render along with it.
Searching the whole tree for the same shape (a client file calling
Utils.<method>() or ReactiveCache.<method>() without importing it) found
two more real, independent instances:
- client/components/settings/notificationSettingsPopup.js's
currentBoard() called Utils.getCurrentBoardId() unimported.
- client/components/main/bookmarks.js's four helpers/events called
ReactiveCache.getCurrentUser() unimported - the header bookmarks/Starred
feature.
- client/lib/tests/Utils.tests.js did `import '../utils';` (a bare
side-effect import) and then used the bare `Utils` global throughout -
never actually reached by the fast Node suite (a mocha/browser test),
but would have thrown the same way if run.
None of this is caught by rspack's build (it does not type-check or
cross-check imports app-wide) or by tests/run-node-suites.cjs (nothing
exercises these code paths with the name deliberately left undefined) -
only the browser, live, the moment that render actually runs.
tests/clientSingletonImports.test.cjs sweeps every client/**/*.js file for
a call to Utils.<method>( or ReactiveCache.<method>( with no matching
import, so this shape cannot reappear anywhere else undetected.
Verified against a real Meteor boot (`meteor run`) in-sandbox.
Thanks to xet7 !
Reported directly: clicking a minicard did not open the card popup, with
the browser console showing "Error: No such function: isDateFormat" from
Template.cardFieldSectionDates. cardDetails.jade was split into several
per-section templates (cardFieldSectionLabels/Dates/Members/
DependenciesAndSort/CustomFields/VoteAndPoker), plus cardDetailsActionsPopup
and activities.jade are separate templates entirely - but twelve helpers
those templates actually call (isDateFormat, canShowCustomFieldsOnCard,
stickers, isWatching, dueDateChangeCount, getLocations, getDependencyCards,
customFieldsGrid, showActivities, showVotingButtons,
showPlanningPokerButtons, currentSwimlaneListsSorted, isCurrentListId) were
only ever registered on Template.cardDetails.helpers - template-local, so
invisible to every template that isn't cardDetails itself. Blaze only
surfaces this the moment that piece of UI actually renders (an
autorun/Tracker throw, not a build error), which is why it passed the
Node test suite and even a `meteor build` cleanly and only broke live.
Moved all twelve to Template.registerHelper (global), matching the
pattern the file already uses for isSectionOpen (this file) and
canModifyCard (client/config/blazeHelpers.js) - both deliberately global
for the same reason. The remaining Template.cardDetails.helpers entries
(orderedCardFieldSections, cardMaximized, cardCollapsed, presentParentTask,
linkForCard, isVerticalScrollbars, isLoaded) are confirmed used only from
cardDetails.jade itself, so they stay template-local.
tests/cardFieldSectionHelperScope.test.cjs pins all twelve as globally
registered and confirms none are shadowed by a stale local copy.
tests/recentIssueRegressions.test.cjs's currentSwimlaneListsSorted
extraction updated for the new registerHelper shape (behavior unchanged).
Verified against a real Meteor boot (`meteor run`) in-sandbox.
Thanks to xet7 !
The user's own ./build.sh run reproduced it directly: "[uncaughtException]
WeKan is stopping: Error: Invalid definition for sort field: 'decimal' is
not a supported property", thrown from SimpleSchema's own constructor the
moment the server started - before any board could load. `decimal: true`
is not, and has never been, a property SimpleSchema recognizes (its
schemaDefinitionOptions list is autoValue/defaultValue/label/optional/
required/type, plus WeKan's own extendOptions(['index', 'unique']) in
imports/simpleSchema.js); nothing exercises that validation under a plain
Node test, which is why it slipped through review. `type: Number` already
allows fractional values with no extra flag - the same as Lists' own
`sort` field, which this one was deliberately written to mirror (see the
field's own comment) and which never had this property either - so
removing it changes nothing about what the field accepts.
tests/customFieldsSortSchema.test.cjs pins the sort field's definition
against SimpleSchema's actual valid-property list and sweeps every other
file under models/ for the same shape, so it cannot reappear anywhere else
undetected by a Node-only test run.
Verified against a real Meteor boot (`meteor run`) in-sandbox: reproduced
the crash before this commit, starts cleanly after.
Thanks to xet7 !
Two text lines under an if/else in comments.jade's reply banner started
with a mustache tag directly, with no leading `|` marker - the pattern
every other text-content line in the codebase uses. build.sh's dev build
warned "missing space before text" for both; harmless (the build still
compiled), but noise on every build. Added the `|`.
The user's own ./build.sh run reproduced it directly: "Error: Cannot find
module '/models/settings'" thrown from packages/wekan-ldap/server/ldap.js
the moment the compiled server actually started (rspack's own build only
warns about this - node test suites never catch it either, since they run
these files with plain Node, outside Meteor's package linker). A local
package under packages/ is its own isolated build unit and cannot import
an app-tree module by absolute path ('/models/...', '/server/...'), static
or dynamic, import or require - that only resolves by accident, if at all.
Four packages had this shape:
- packages/wekan-ldap/server/ldap.js imported Settings and resolveConfigValue
from /models/settings and /models/lib/configResolver directly (added by the
recent LDAP Admin Panel override feature). configResolver's pure functions
are now vendored into packages/wekan-ldap/server/configResolver.js; Settings
access is injected instead, via setLdapSettingsAccessor(), wired once at
boot by the new server/ldapAdminSettingsBridge.js (imported from
server/imports.js).
- packages/wekan-oidc/oidc_server.js required /models/lib/oauth2ClientSecretJwt
(pure, Node crypto/fs only) - vendored the same way, into
packages/wekan-oidc/oauth2ClientSecretJwt.js.
- packages/wekan-accounts-saml/saml_server.js and
packages/wekan-accounts-cas/cas_server.js each lazily required
/server/lib/canary inside their account-conflict guard's try/catch, so it
failed silently (caught, not crashing boot) rather than ever actually
logging the attempt. canary.js is stateful (Meteor/Mongo-backed rate
limiting), so it can't be vendored the same way; server/lib/canary.js now
sets global.__wekanTripCanary once at module load (the Node process itself
is the one thing both sides can reach without either importing the other),
and both packages call through that instead.
Also found while wiring this up: packages/wekan-accounts-saml/saml_server.js
imports the npm package body-parser without declaring it in package.js's
Npm.depends, which crashed boot the same way once it stopped finding the
copy some unrelated app dependency happened to hoist into node_modules.
Added it to Npm.depends.
Tests: tests/packageAppImportBoundary.test.cjs sweeps every file under
packages/ for an app-tree absolute import (the negative check - nothing
under packages/ may do this, anywhere) and pins both vendored copies'
behavior against their app-tree originals so they cannot silently drift.
tests/securityAdvisories20260825.test.cjs's CAS account-conflict assertion
updated to match the new global.__wekanTripCanary bridge call.
Verified end to end: bootstrapped Meteor 3.5.2 in-sandbox and ran the real
dev server (`meteor run`) before and after - it reproduced both the
Settings/configResolver crash and, after fixing that, the body-parser
crash, exactly as reported; after this commit it compiles and starts
cleanly with neither.
Thanks to xet7 !
Fills the Roadmap board-view, popup-title, notification-settings and
chart-forecast strings added since these locale files were last
completed. Aragonese also picks up two older admin-people keys
(last-active/currently-online) that were still untranslated.
Fills the ~57-59 placeholder keys added for the Roadmap board view,
Two-Factor Authentication, forecast chart, list sync and related popups
in each of these locales, using each file's own existing translations
and general kanban/dictionary terminology as reference. Placeholders
(__remaining__, __average__, __date__, %s) are preserved unchanged.
Some translations (constructed/lesser-resourced languages such as
Cornish, Sakha, Buryat, Aromanian, Bislama, Kalaallisut) are done with
lower confidence and may need human review.
The board-export-zip and OIDC-redirect-loop entries still linked their
pre-history-move hashes (9c04e5314, d3a217186); 0c77553b8 repointed the
rest of the file but missed these two, so
tests/changelogEntriesBelongToTheirRelease.test.cjs correctly flagged
v11.67 as linking commits it does not contain. Repointed to the current
hashes (f383fe9b3, f3c39f3b2).
models/lib/adminUrls.js's people.panes gained a notifications entry
(Admin Panel -> People -> Notifications, the site-wide default for the
3-tier notification-settings popup) that was never added to
docs/Features/Admin-Panel/People/README.md's pane index, so the pane
existed in the product and nowhere in the docs.
wekan-accounts-saml and its @node-saml/node-saml dependency are already
declared in .meteor/packages and package.json; .meteor/versions and
package-lock.json had not been regenerated to match since #708 landed.
listBody.jade's more-options assignee checkbox called a helper directly
inside checked=(...), a call-expression attribute the Jade-to-Blaze
compiler does not support; rewritten as the mustache-attribute pattern
checked="{{#if helper arg}}...{{/if}}" used elsewhere in the codebase.
settingBody.jade's email-template textareas passed a bare numeric Jade
attribute rows=4, which the compiler also rejects; quoted as rows="4".
Both surfaced as compile failures in ./build.sh's development build.
Fills the Roadmap board-view, popup-title, notification-settings and
chart-forecast strings added since these locale files were last completed.
ru_RU also fixes the ru-RU.i18n.json symlink target.
Fills the placeholder keys added for the Roadmap board view, popup titles
(subtask, card restore, create-board-from-card, archive-all, clone-board,
list-sync), Two-Factor Auth strings, notification-settings and forecast
chart keys that were still sitting at the English source value.
git-mirror-update.sh/.bat were renamed to mirror.sh/mirror.bat, but
buildScriptParity's SKIP list and gitMirrorUpdateScripts's reads still
used the old names, so the parity check flagged mirror.sh/mirror.bat
as unreachable-from-menu and the mirror script test failed to find its
files at all.
(Hiragana), Odia, Telugu, Klingon, Uyghur and Xhosa translations.
The report-chart forecast strings, Roadmap view, list-sync popup and
two-factor-authentication popups were missing their translations entirely
in these locale files (the key was absent, not merely left as English),
which made several upcomingXPlaceholderRepair node test suites fail: they
compare every locale value's __placeholder__/%s inventory against the
English source, and a missing key reads as an empty inventory instead of
matching English's.
Translated directly from each language's vocabulary/grammar, preserving
every __placeholder__ and %-token exactly. Lower confidence on Klingon
(tlh), which has no canonical vocabulary for modern software concepts;
still better than the untranslated key it replaces.
Thanks to xet7 !
Each of these pinned a shape that changed on purpose earlier today, not a
regression - updated the assertion and said why in the test:
- adminPageRows: peopleListChanged() now also runs from the #2731 GDPR
anonymizeUser handler, so the client-count guard expects 3 call sites,
not 2.
- boardItemLinks: the reveal-clearing loop only applies to route-param
reveals (swimlane/list), not the hash-driven comment/activity ones; and
the "same block" extraction for the SILENT comment-delete canary test
needs to anchor on the DELETE route specifically now that the edit route
has an identically-shaped guard right above it.
- boardsVisibilitySettings: wekan/wekan#3069's new "external link pattern"
admin-pane group sits between the URL group and the product-name group.
- canaryCoverage: same anchor fix as boardItemLinks, for the SILENT
REST-comment-delete canary test.
- cardDetailsAddIcons: the block-boundary heuristic stopped at the first
"else" it found, which is now the inner "unless currentUser.isWorker"
branch added for the Worker role - it has to stop at the outer
"if canModifyCard" else instead.
- cardsCountSwimlaneScope: the naive substring search for the cardsCount()
helper now matches an unrelated comment mentioning "cardsCount()" earlier
in the file (on listCardsForSummary); anchored on the actual definition
line instead.
- crossBoardParentCardLeak: an eleventh visibleLinkedCardIds() cursor
(CardTextNotes) was added alongside the other linked-card content
cursors.
Thanks to xet7 !
docker-compose.yml's WeKan service is supposed to be identical, comment for
comment, across the four docker-compose-ferretdb-v1-*.yml backend files -
the whole point of having one per backend is that a user reading any of
them configures the same WeKan. The four backend files still had the bare,
undocumented "#- SAML_ENABLED=true" block from before the SAML 2.0 login
feature's explanatory comments were written; they now carry the same
per-variable comments docker-compose.yml does.
Thanks to xet7 !
client/components/boards/roadmapView.js imports frappeGantt.js directly for
loadGanttLib/cardsToTasks/popupDetailsHtml, but that module registers
Template.frappeGanttView.* without importing frappeGantt.jade. Whichever
module reaches it first - which can now be roadmapView.js, well before
client/features/gantt.js's own import list gets to the .jade - registers
helpers/events against a template that does not exist yet, which throws and
stops the rest of the module evaluating. Same fix this class of bug already
gets for every other component more than one other module imports.
Thanks to xet7 !
client/lib/revealBoardItem.js's permalink reveal (#4757) is one-shot:
following a #comment-<id>/#activity-<id> link sets revealCommentId/
revealActivityId in Session, and the board scrolls to and highlights that
element once. The card and board routes already cleared revealSwimlaneId/
revealListId on every navigation so a stale swimlane/list reveal could not
fire on the next board, but never cleared the two comment/activity keys -
so following a comment permalink and then opening a different card could
still scroll to and highlight the old comment once the first card's board
rendered again.
Thanks to xet7 !
peopleMenu() draws a "Notifications" row (the admin-level default for the
3-tier Notification Settings system) right below Email, but
ADMIN_PAGES.people.panes had no slug for notify-setting, so the row could
not be linked to or deep-linked the way every other row on the page can be.
Thanks to xet7 !
- headerBars.test.cjs: the starred-boards count moved into the user
model's own starredCount() (now covering swimlanes/lists/cards too,
#1172), so the test now checks the header delegates to it instead of
pinning the old inline boards+pages arithmetic.
- notificationEmailHtmlSafety.test.cjs: the notification subject is `let`,
not `const` - the #2022 admin-template override reassigns it through
the same safeEmailSubject() guard - so the regex now matches `let`. The
guard itself was already intact at every call site.
- restCommentDeleteAcl.test.cjs / restSecurityAdvisories.test.cjs: a
comment-edit PUT route was added (with the correct
Authentication.checkBoardAccess + assertCanMutateComment(req.userId, ...)
pair, same as DELETE). restCommentDeleteAcl's negative test previously
banned any PUT outright; it now asserts the PUT carries the same ACL
instead. restSecurityAdvisories' commentCreate route slice ended at the
DELETE handler string, so it now silently swallowed the new PUT's
checkBoardAccess call and failed a doesNotMatch aimed at POST; the slice
now stops at the PUT handler, with its own assertions pinning the PUT's
membership + object-ACL checks.
- rulesDateFieldTrigger.test.cjs: the "text contains" trigger landed
between r-when-a-card-matches-advanced-filter and the four date
triggers in every locale file (en.i18n.json included), so the ordered
key list now expects it there too.
Thanks to xet7 !
duplicate untracked km-KH/ru-RU language files, and six title-less popups.
- docs/Features/Cards/Scrum.md linked ../../DragDrop/Drag-Drop.md and
../../Lists/WipLimit/WipLimit.md, one directory level too high from
docs/Features/Cards/; both 404'd.
- imports/i18n/data/km-KH.i18n.json and ru-RU.i18n.json had drifted into
independent copies of km_KH.i18n.json/ru_RU.i18n.json instead of being a
symlink to the file Transifex actually writes, so the registry's
"km-KH"/"ru-RU" entries loaded a stale duplicate and ru-RU lost two keys
that only landed in ru_RU.i18n.json. Restored the symlinks.
- Six popups (Add Existing Subtask, Restore Card to Timeline, Clone Board,
Create Board From Card, Archive All [list] Cards, List Sync) had no
`<name>Popup-title` key, so they rendered with no header and so no close
button. Added the title key to en.i18n.json and every locale file (left
as the English placeholder where no translation exists yet, per the
untranslated-everywhere rule).
- imports/i18n/data/ace.i18n.json, ba.i18n.json and three other locales
were missing text-contains-trigger-label/-description entirely, shifting
every key after them out of position relative to en.i18n.json.
Thanks to xet7 !
Board Settings description publication, Notification Settings wiring and
two unscaled font sizes.
- allowsSpentTime/allowsSpentTimeOnMinicard have defaultValue: true in
models/boards.js but were missing from schemaUpgradeSteps.js's
BOARD_ALLOWS_TRUE_DEFAULTS, so a board created before those flags existed
would read them as undefined/false and hide its spent-time badge.
- customPrivateBoardDesc/customPublicBoardDesc are read by settingBody.jade
but were not in server/publications/settings.js's SETTING_FIELDS, so the
fields always rendered empty and saving them looked like it did nothing.
- notificationSettingsPopup.jade/.js are used by peopleBody.jade but were
never imported into client/features/settings.js, so the template compiled
to nothing and the popup did not exist at runtime.
- timelineView.css and two rules in minicard.css still used bare px
font-size values instead of calc(Npx * var(--wekan-ui-font-scale, 1)),
so the UI font-size preset did not reach them.
Thanks to xet7 !
Fix TypeError: string.toLowerCase is not a function server unhandledRejections
reported in production. The registration invitation-code check in
Users.after.insert() read doc.authenticationMethod.toLowerCase() unguarded,
but authenticationMethod is only set for oauth2/ldap signups - a normal
password/invitation signup left it undefined and crashed this hook on every
insert whenever disableRegistration was on; doc.emails[0].address was also
read unguarded. The buffered notification-email sender likewise read
user.emails[0].address.toLowerCase() unguarded, crashing when a user (e.g. a
header-auth/LDAP account) has an empty emails array. The CSV/TSV importer's
header-row mapping read headerRow[i].toLowerCase() unguarded, which could
throw on a sparse row cell that isn't a string.
A full audit of every server-reachable .toLowerCase() call site (server/,
models/, packages/) found the rest already guarded (typeof checks, ||
'' fallbacks, or values sourced from validated schema fields).
Thanks to xet7 !
Reuses each locale's own existing translation of the equivalent
checklist-reset-interval strings (same Off/Daily/Weekly/Monthly concept, and
an "Automatic reset"-style title), so every locale gets a real translation
rather than an English placeholder.
Thanks to xet7 !
A card can now be set to automatically spawn a fresh copy of itself, in the
same list, on a recurring schedule (daily/weekly/monthly) - the same idea
Kanboard has for a recurring task, applied on-premise with no external
dependency. Reuses the exact mechanism already built for a checklist's
automatic reset: a recurrenceInterval field on the card, the same
quave:synced-cron job infrastructure, and the same due-date arithmetic
pattern (models/lib/cardRecurrenceSchedule.js mirrors
models/lib/checklistResetSchedule.js). The card's "..." menu gets a new
"Card recurrence" entry, next to Save card as template, opening a popup
shaped exactly like the checklist's "Automatic reset" popup.
Thanks to xet7 !
Board View / Timeline (Step 1 of the maintainer's spec): a new menu entry
right after Time, wired end to end like every other view - the
boardChangeViewPopup entry, Utils.setBoardView('board-view-timeline'), an
isViewTimeline() helper and boardBody.jade branch, the two client/lib/utils.js
whitelist arrays, the profile.boardView schema allowedValues, a tooltip-name-
map entry, and template/stylesheet registration in client/features/boards.js.
The view renders a horizontal row of clickable markers built from the
board's distinct activity timestamps (sampled to 50 when there are more),
plus a "Now" marker for the live board. Clicking a marker calls the already-
built, already-tested models/lib/boardTimeline.js's pure
reconstructBoardStateAt(cards, activities, timestamp) - this file does not
reimplement history reconstruction - and renders the result read-only,
grouped by reconstructed list: title, description snippet, labels, members,
due date and an archived badge.
Step 2: each card in a historical view gets a "Restore to this state"
button. It applies the RECONSTRUCTED field values to the card's CURRENT
document by calling only the card's own existing setters one at a time
(setTitle, setDescription, move, addLabel/removeLabel, assignMember/
unassignMember, setDue) - never a bulk update that bypasses them - so each
write is logged as its own Activity by the existing hooks and the restore
itself becomes new, fully visible history. Nothing is deleted. A
confirmation popup (Popup.afterConfirm, the same pattern used elsewhere)
gates the action since it changes the board's current state.
Deliberately deferred, per the task's own scope discipline: "selective
per-member change removal within a time period" is a separate, higher-risk
mutation feature left for a dedicated future pass.
tests/boardViewMenu.test.cjs's VIEWS table gets the new entry (icon
fa-history, template timelineView, helper isViewTimeline) and its HR_AFTER
separator moves from Time to Timeline. tests/boardTimelineRestore.test.cjs
pins that the restore path only calls the card's own setters (with a
negative test scanning for a direct Cards.update/updateAsync bypass), that
the restore button only renders while viewing a historical timestamp, and
that a confirmation step is required before restoring.
Added "Timeline" and its five other UI strings to en.i18n.json and to every
other locale file with real per-language translations (not English
placeholders); verified with fill-translations.mjs --missing.
Thanks to xet7 !
A board member with write access can now configure list sync from the
List hamburger menu (new "Sync" item, badge shows enabled/paused status)
instead of only through the Meteor console: pick a source type from the
existing SYNC_CAPABLE_SOURCES (Jira/GitHub/GitLab/Gitea/Forgejo), set the
URL/project key, see current status (enabled, last synced, last error)
and run "Sync now" for immediate feedback. This is UI wiring only - it
calls the existing setListSyncSource/hasListSyncCredential/syncListNow
methods (server/methods/listSync.js) exactly as defined; the sync backend
itself is untouched.
The credential field is write-only, the same discipline as the LDAP
Admin Panel override's bind password: it always renders with a hard-coded
empty value, is never pre-filled with the real token even when one is
already stored, and the popup shows only a boolean "a credential is set"
status from the existing hasListSyncCredential method.
Added the new UI strings to en.i18n.json and translated them into all
locale files - real translations for languages this batch covered, and
the English source as a starting value (never a human translation
overwritten) for the remainder pending further translation.
Thanks to xet7 !
A board member with write access can now configure list sync from the
List hamburger menu (new "Sync" item, badge shows enabled/paused status)
instead of only through the Meteor console: pick a source type from the
existing SYNC_CAPABLE_SOURCES (Jira/GitHub/GitLab/Gitea/Forgejo), set the
URL/project key, see current status (enabled, last synced, last error)
and run "Sync now" for immediate feedback. This is UI wiring only - it
calls the existing setListSyncSource/hasListSyncCredential/syncListNow
methods (server/methods/listSync.js) exactly as defined; the sync backend
itself is untouched.
The credential field is write-only, the same discipline as the LDAP
Admin Panel override's bind password: it always renders with a hard-coded
empty value, is never pre-filled with the real token even when one is
already stored, and the popup shows only a boolean "a credential is set"
status from the existing hasListSyncCredential method.
Added the new UI strings to en.i18n.json and translated them into all
locale files - real translations for languages this batch covered, and
the English source as a starting value (never a human translation
overwritten) for the remainder pending further translation.
tests/listSyncUiWiring.test.cjs pins: the credential field can never
render or return a real token value (positive + negative source checks),
the status display reads syncSource.lastSyncedAt/lastSyncError/enabled
off the list's own already-published, credential-free fields, the
Meteor.call sites match the existing method names/argument shapes, the
source-type picker only offers SYNC_CAPABLE_SOURCES, and every locale
file has a non-empty value with the %s placeholder intact for every new
key.
Thanks to xet7 !
models/lib/boardTimeline.js's reconstructBoardStateAt(currentCards,
activities, asOfTimestamp) computes what each card's title, description,
listId, swimlaneId, labelIds, members, assignees, dueAt and archived flag
would have been at a given moment, by taking the card's CURRENT state and
undoing every activity after that moment in reverse-chronological order.
It reads the board's existing Activities log as the source of truth rather
than storing separate snapshots, and is pure/read-only: no Mongo/Meteor
access, no mutation of its inputs, and no Activity is ever written or
deleted.
Covers createCard, a-changedTitle, a-changedDescription, a-dueAt, moveCard,
archivedCard/restoredCard, joinMember/unjoinMember, joinAssignee/
unjoinAssignee and addedLabel/removedLabel - every activityType that
currently records enough old/new detail to be reversed. moveCardBoard,
setCustomField/unsetCustomField and deleteCard are known but not reversed;
cross-board moves are surfaced via unreversedActivityTypes rather than
silently left unhandled.
This is Step 1 of the "Board View / Timeline" feature only: the read-only
reconstruction function and its tests. The Timeline board-view UI, the
per-card restore action and the selective per-member change removal
described in the same request are not implemented in this commit - see the
CHANGELOG entry for what is and is not delivered.
tests/boardTimeline.test.cjs pins each activityType's undo transform, a
multi-step history reconstructed at several points, that the function
never mutates its inputs, and a negative test scanning the module's source
for any Activities removal call.
Thanks to xet7 !
A WeKan list can be marked with a syncSource (type/url/projectKey) and a
server-only credential (models/listSyncCredentials.js, never published).
server/listSync.js registers a quave:synced-cron job, reusing the SAME
scheduling infrastructure the checklist-auto-reset job uses, that fetches
each synced list's current items and reconciles them against WeKan
(models/lib/listSyncReconcile.js, pure/unit-tested): new items create
cards, changed items update them, and items that disappeared upstream are
ARCHIVED rather than deleted, so old entries stay in the list's history.
Fetching (server/lib/listSyncFetch.js) and parsing reuse the existing
one-time-import parsers in models/lib/externalParsers.js (parseJira is
new there; parseGithub/parseGitlab/parseGitea gained externalId) instead
of a second implementation. Jira works end to end; GitHub/GitLab/Gitea
share the same job and reconcile logic via their existing parsers.
Thanks to xet7 !
LDAP Connection button.
Every LDAP_* setting server/authentication.js and packages/wekan-ldap read
straight from process.env can now be overridden from Admin Panel / Login,
with an explicit admin value winning over the env var and the env var
winning over nothing (models/lib/configResolver.js's resolveConfigValue(),
pure and unit-tested for the precedence and for its 'admin'/'env'/'default'
source tag). The Admin Panel LDAP section shows, next to every field,
which source is currently in effect - an env var name, "Admin Panel", or
"Unset" - so it is always clear whether a value comes from the environment
or from an admin override.
The bind password never reaches the browser: it is stored in the new
Settings.ldap.bindPassword field, which server/publications/settings.js
deliberately never publishes (only the boolean ldap.bindPasswordSet is).
The password input starts empty and an empty submission leaves the
existing value/source untouched, matching the existing mail-server
password field's pattern. hasConfigValue() is the parallel, secret-safe
resolver: it returns only a boolean and a source, never the value, and a
negative test fuzzes several secret shapes through it to prove that.
Found while wiring this up: packages/wekan-ldap/server/testConnection.js's
existing ldap_test_connection method had its isAdmin check commented out
("TODO: this needs to be fixed - security issue"), so any authenticated
user - not only an admin - could trigger a real LDAP bind attempt against
the configured directory. Fixed to require isAdmin, the same check every
other admin-only Settings method uses, before any connection is attempted.
A new "Test LDAP Connection" button in Admin Panel / Login calls this
method against whichever config (admin override or env var) is currently
resolved and shows the result - success or the directory's own error -
inline, satisfying the "get back error message visible at admin panel"
request without adding a second LDAP client dependency.
Switching between LDAP, OAuth2, SAML and password login already has its
own UI (the Login pane's "Default Authentication Method" selector plus
each method's own enabled flag) and needed no separate switcher; this only
extends "enabled" itself to be admin-overridable, the same as every other
LDAP field.
Scope: LDAP is covered end to end (override + test-connection). OAuth2/
SAML/CAS's env vars are unchanged and stay env-only for now - the resolver
is written to extend to them, but doing so was out of scope for this pass.
Tests: tests/configResolver.test.cjs (precedence, source tagging,
hasConfigValue's secret non-leak, redactCredentialsInUrl for the composite-
connection-string case); tests/ldapAdminOverrideSecurity.test.cjs (the
publication never sends ldap.bindPassword, a whole-tree negative sweep for
any OTHER publication doing the same, the isAdmin gate on
ldap_test_connection runs before any connection attempt, and the method's
response never carries the password); tests/settingPublishedFields.test.cjs
extended to understand dotted/sub-document published fields so it keeps
checking the LDAP section's currentSetting.ldap.* reads against what is
actually published.
Thanks to xet7 !
A card's own description was the only place to put markdown text, so anything
beyond a single block had to be crammed into it. This adds CardTextNotes: a
small collection of named markdown notes per card, modeled on Checklists (a
denormalized boardId, the same publish/allow/deny shape, the same
GHSA-gv8h-5p3p-6hx7 cross-board-move guard).
Each note renders as a tile with its title and a markdown-rendered preview
(the `viewer` template). "Add text note" and a note's "Edit" open a popup
that reuses the description's own `editor`/`viewer` widgets verbatim - no new
markdown editor was written. "Delete" removes the note, scoped to its own
_id.
Wired into the reactive cache (getCardTextNote/getCardTextNotes, matching the
CardComments pattern), the board/linked-card/lazy-window/single-card
publications, and server/permissions/cardTextNotes.js.
tests/cardTextNotes.test.cjs pins: the model's cardId/boardId scoping, the
allow/deny permission shape, the popup's reuse of `editor`/`viewer` (positive:
+editor is used; negative: exactly one `editor` and one `viewer` template is
declared anywhere under client/components/{cards,main} - the whole tree, not
just the new files, so a competing widget cannot be introduced elsewhere
either), and that add/edit/delete are scoped calls rather than broad
selectors.
Thanks to Lapin0t and xet7 !
Closes#595,
substring check, an overly-permissive regex range and a no-op replace.
- models/lib/cardUrlAutolink.js and packages/markdown/src/
template-integration.js (kept in sync, per their own comments): the
card-title markdown-link escape only escaped ']', not the backslash
that precedes it, so a title ending in a raw backslash escaped the
']' this code inserts to close the label instead of the label
actually closing. Escape '\' before ']'.
- server/lib/documentGif.js: plainSearchText's control-character strip
used literal raw control bytes inside the regex character class
instead of \x escapes, so CodeQL flagged the range as unverifiable
(adjacent control bytes are visually indistinguishable, so a
boundary could silently shift). Rewritten with explicit \x escapes,
byte-for-byte equivalent to the original range.
- tests/notificationEmailUrlLink.test.cjs: built a dynamic RegExp by
hand-escaping only '/', leaving every other meta-character -
including backslash itself - unescaped. Added the same escapeRegExp
helper already used elsewhere in the codebase.
- tests/oauthLogoutUrl.test.cjs: asserted a returned URL did not
contain a hostname via `.includes()`, a substring check a
confusable/query-embedded hostname can fool either way. Compare the
parsed `new URL().hostname` instead.
- tests/boardCreationAdminOnly.test.cjs: `.replace(/ /g, ' ')` was a
no-op (replacing a space with itself); the actual intent was to
collapse runs of spaces, `.replace(/ +/g, ' ')`.
Every fix has a positive test proving the corrected behaviour and a
negative test reproducing the exact bypass/bug CodeQL flagged. None of
these cross a security boundary on their own (the markdown-link title
escaping is a rendering-correctness fix - DOMPurify still sanitizes
the final HTML regardless, per the existing code comments; the rest
are test-only assertion bugs), so no Admin Panel security-log entry
applies.
Thanks to GitHub CodeQL and xet7 !
Following the JSON-export truncation report, every IMPORT source was
audited end-to-end the same way the export side already was: WeKan JSON,
WeKan zip, Trello JSON/API/zip, CSV/TSV, Excel, Jira, Kanboard, Markdown,
NextCloud Deck/OpenProject/GitHub/GitLab/Gitea/Forgejo/Asana/Zenkit, and
ICS. Every one of them is genuinely reachable from the UI and produces a
real board - no dead popups, no "Mapper"-only stubs. The WeKan JSON
round-trip (models/wekanCreator.js) restores swimlanes, lists, cards,
checklists, labels and custom fields without dropping any of them, and
attachment import already works both from inline base64 content and from
a bare URL reference (models/wekanCreator.js), so it needs no inline
attachment bytes and is unaffected by the export side now omitting them.
The one real historical bug found in this area, attachments always
empty in JSON export, was already fixed (commit 643e2738b) and is
unrelated to import.
The only genuine gap was test coverage: CSV, Jira and Kanboard import had
real, working parsers but no dedicated tests. This adds
tests/csvCreator.headerMapping.test.cjs, mirroring
CsvCreator#mapHeadertoCardFieldIndex (standard headers, aliases, and the
customfield-<name>-<type>-<extra> dropdown/dropdownMultiSelect/currency/
plain variants), and tests/kanboardJiraCreator.import.test.cjs, mirroring
KanboardCreator's unix-timestamp date parsing and column/swimlane
derivation, plus JiraCreator's issue-link-to-card-dependency mapping
(blocks/is-blocked-by/related-to, unknown targets, self-links and
duplicate links). Both modules import Meteor/model code and can't run
under plain Node, so the tests re-implement the exact production logic
as a faithful copy, following the existing convention in
tests/trelloCreator.import.test.js and the wekanCreator.*.test.js suite.
Thanks to xet7 !
Auditing every export format (board JSON/CSV/iCal/HTML/dependency graph/
Kanboard/Trello/Jira/Deck/OpenProject/GitHub/GitLab/Gitea/Forgejo/Asana/
Zenkit/Markdown, and PDF/Excel for all 13 chart/report views) against its
server route, its builder function and the UI entry that offers it found
every one genuinely wired end-to-end - except this test, which asserted
'time' was the LAST entry of models/exportCharts.js's CHART_KEYS Set.
That stopped being true once 'pulse' was appended after it, so the test
failed even though the export itself works correctly. Loosened the regex
to match 'time' anywhere in the Set literal.
Thanks to xet7 !
A "Roadmap" view for organizing/summarizing cards by version or release
milestone in a timeline layout, similar in spirit to a ProductPlan-style
release roadmap chart. Structurally this is the existing Frappe Gantt view
grouped by the VALUE of a board custom field (a "Version"/"Release"-style
text or dropdown field) instead of one flat list of cards: a dropdown lets
the user pick which custom field to group by (defaulting to the first
text/dropdown field, or a clear empty-state message when the board has
none), each distinct value renders as its own row, and every row is its own
small Frappe Gantt timeline built from the SAME cardsToTasks()/loadGanttLib()
code the plain Gantt views already use, plotted over the same
startAt/dueAt/endAt card dates - no new charting library, no custom-field
creation UI, this view only consumes fields the board already has.
client/components/boards/roadmapView.js reuses
client/components/gantt/frappeGantt.js's loadGanttLib/cardsToTasks/
popupDetailsHtml verbatim, and models/lib/chartCalculations.js's
computeCardsByCustomFieldGroup does the pure "group cards by a custom
field's value" fold (mirroring computeCardsByAssigneeGroup's shape: a card
with no value falls into a "no value" sentinel group, sorted last).
Registered in client/features/boards.js like every other board view.
Extends tests/boardViewMenu.test.cjs's VIEWS array for the end-to-end
menu/helper/template/stylesheet wiring, and adds unit tests (positive,
negative and sort-order) for computeCardsByCustomFieldGroup and its
translateGroupLabel handling in tests/chartCalculations.test.cjs.
Thanks to datenwort and xet7 !
Closes#627,
Starring a board already existed (profile.starredBoards, toggleBoardStar
in models/users.js / server/models/users.js). This generalizes that same
per-user id-array shape to profile.starredSwimlanes, profile.starredLists
and profile.starredCards, each with its own toggleSwimlaneStar /
toggleListStar / toggleCardStar Meteor method that checks the id and
requires a login the same way toggleBoardStar does.
A Star/Unstar row was added to the Swimlane, List and Card hamburger menus
- a reading action, alongside Copy link and History, above the rows that
change the board. The list's own per-board `starred` field
(client/components/lists/listHeader.js isStarred()/.star(), used for the
sticky/pinned-list highlight) is untouched; the new per-user star uses its
own isListItemStarred helper and js-star-list-item row.
A new "Starred" page (/starred-items) lists everything the current user
has starred, grouped by type, reusing the "open card in place" popup
mechanism myCards/myAttachments already use for the card group. It is
reachable from the "All Pages" member menu next to My Cards / My Due
Cards / My Attachments.
The header bookmarks dropdown (starredBoardsPopup) gained three more
capped sections - Starred Swimlanes/Lists/Cards, five each, most-recently-
starred first - with a "see all" link to the uncapped Starred page. Both
the dropdown and the Starred page read the same starredItemsByType() query
(client/components/main/header.js, imported by starredItems.js), so there
is one definition of "what is starred" rather than two that could drift.
tests/starredItems.test.cjs pins the persistence shape for all three new
types, that starredCount() sums all five starred kinds, that the shared
query has exactly one definition, and that the new i18n keys are used by
all three menus. tests/starredPages.test.cjs's count assertion was updated
to match: the count now goes through the shared starredCount() aggregate
rather than two lengths added inline, still covering every starred kind.
The new labels (Star/Unstar, Starred Swimlanes/Lists/Cards, "See all
starred items", the empty-state message) are added to en.i18n.json and to
every other locale file with real per-language translations.
Thanks to chris-kwng and xet7 !
Closes#1172,
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
The calculation (computeRemainingTimeSum/formatRemainingTime in
models/lib/chartCalculations.js), the server wiring
(server/lib/boardChartData.js's 'time' chartKey branch), the PDF/Excel
export section (models/lib/chartExportRows.js), the new
"board-status-remaining-time-total" i18n key in all locale files, and
the unit tests for #1121 landed already, bundled into concurrent
commits on the same shared files (3480e8a9456e01cabe3ff9997df487bf5cafc83a
and the Pulse board view commit). This commit adds the two pieces that
were still uncommitted: the Time view's own summary row
(client/components/boards/timeView.jade) and its helper
(client/components/boards/timeView.js), which render that total the
same "X days, Y hours" way the export already does.
Thanks to Yachikh and xet7 !
Closes#1121,
Adds the entry for the "Filter sidebar changes now update the URL" commit,
under the existing "Board filters" group next to #4540's read-on-load entry,
and updates that entry's closing note now that the write direction exists.
Thanks to netei and xet7 !
Closes#319,
#4540 (963b01ff5) already lets a board be opened pre-filtered from
`?assignee=johndoe`/`?member=janedoe`/`?label=urgent`, read once on board
load. #319 additionally asked for the other direction: applying a filter
from the sidebar should update the URL too, so a manually filtered view is
itself bookmarkable/shareable without hand-typing the query string.
Adds `client/lib/filterQueryParams.js`'s `resolveIdsToUsernames`,
`resolveIdsToLabelNames` and `buildBoardFilterQueryParams` - the exact
inverse of the existing parser, reusing the same `assignee`/`member`/`label`
token vocabulary - and a reactive `list()` getter on `SetFilter`
(`client/lib/filter.js`) so its current selection can be read outside the
sidebar template. `boardBody.js`'s new `syncFilterQueryParams`, run from a
separate `Tracker.autorun`, resolves `Filter.assignees`/`members`/`labelIds`
back to names and writes them via `FlowRouter.setQueryParams` wrapped in
`FlowRouter.withReplaceState`, so toggling a filter replaces the current
history entry instead of piling up a new one per click.
Covered by tests/filterQueryParams319.test.cjs: the id->name resolvers, the
query-param builder (including empty selections clearing their param and
unknown ids being dropped), a full round trip through #4540's own
`parseBoardFilterQueryParams` proving both directions agree, and source
checks pinning how boardBody.js wires it up.
Thanks to netei and xet7 !
Closes#319,
The Settings schema fields (inviteEmailSubjectTemplate/BodyTemplate,
activityEmailSubjectTemplate/BodyTemplate), their publication, and the
server-side use in sendInvitationEmail() (server/models/settings.js) and
the buffered activity-notification email (server/notifications/email.js)
already existed, reusing models/lib/ruleVarsSubstitute.js's substituteVars()
- the same {token} substitution the #3304 rule "send email" action uses -
but had no Admin Panel UI to set them, so an admin could not actually reach
the feature. Adds the missing fields (Admin Panel / Email / Email Templates)
with their own Save, right below the SMTP settings.
Left blank (the default on every existing install), WeKan sends its exact
current hardcoded/i18n content for both email types, unchanged. Password-
reset and account-verification emails are deliberately excluded: they stay
hardcoded, since a misconfigured or malicious custom template on a
security-critical email (e.g. one that strips the reset link) would be a
real account-takeover risk.
tests/emailTemplatesCustomization.test.cjs adds regression coverage: an
unset template falls back to exactly the current hardcoded/i18n content,
a set template is substituted through the existing substituteVars() (with
a source-pattern negative test proving there is no second/duplicate
templating implementation), the new Admin Panel labels are translated in
every locale file, and a negative test confirms the password-reset/
verification email code paths (server/lib/resetPasswordEmail.js,
config/accounts.js) never reference any of the four new template fields.
Thanks to saurabharch and xet7 !
Closes#2022,
Auditing the REST API surface against #1037 found two clean CRUD gaps:
every other board sub-resource with GET/POST/DELETE already had a
matching PUT, but a checklist and a comment did not, so editing either
meant deleting and re-creating it.
PUT /api/boards/:boardId/cards/:cardId/checklists/:checklistId renames
a checklist (title only), mirroring the existing DELETE's lookup and
checkBoardWriteAccess check.
PUT /api/boards/:boardId/cards/:cardId/comments/:commentId edits a
comment's text, reusing validateCommentBody and the same
assertCanMutateComment rule (and foreign-edit canary) the DELETE
handler already applies.
tests/restApiEditGaps.test.cjs pins both routes as source-pattern
tests, the same way tests/restApiIdorBatch.test.cjs already does for
this REST surface.
Thanks to mayjs and xet7 !
models/cards.js's cardLabels() hook already inserts Activities documents
with activityType 'addedLabel'/'removedLabel' whenever a card's labelIds
gains or loses a label - wired into a Cards.before.update hook the same way
cardMembers/cardAssignees are, with matching en.i18n.json rendering strings.
Pin that mechanism plus the notification-settings shape it does not yet plug
into, so neither regresses silently.
Thanks to bhagyas and xet7 !
Fixes#572,
The card sortable's connectWith ('.js-minicards:not(.js-list-full)') only
covers each list's card-body area; .js-list-header sits in normal flow
directly above it and does not overlap it, so jQuery UI resolves no
connected container and silently cancels a drop landed precisely on the
header - the card snaps back with nothing happening.
The sortable stop handler now hit-tests the mouseup's own coordinates for a
.js-list-header ancestor and, when found, resolves the same
prevCardDom/nextCardDom/listId/targetContainer a drop at the TOP of that
list's card body would produce, so the existing card.move() mutation and
sort-repair logic are reused unchanged.
Thanks to TylerL-uxai and xet7 !
Fixes#766,
#1476 asked for cycle time, lead time, throughput/velocity, bottleneck
analysis, and completion estimates based on velocity. The first four are
already covered by the existing board report charts: the Cycle Time and
Lead Time views (computeLeadCycleTime), the Throughput Histogram
(computeThroughput), and the Control Chart / Cumulative Flow Diagram / WIP
Run views, which are the standard Kanban tools for spotting a bottleneck
even though none of them is literally named "bottleneck".
The one piece that was missing is a forward-looking projection: at the
recent completion rate, when will the cards still open be done. Add
computeCompletionForecast to chartCalculations.js, reusing
computeThroughput's own weekly series rather than recomputing velocity a
second way - it averages the last 4 weeks of completions and divides the
remaining open-card count by that rate to project a date. Wire it into the
Throughput Histogram's server data (server/lib/boardChartData.js) as a
`forecast` field alongside the existing `series`, and show it as a plain-
text note under that chart (client/components/boards/charts/boardCharts.js
and .jade), with three new i18n strings for the none-remaining/no-velocity/
projected cases.
implemented.
#567 ("Hide empty lists when filtering items in a board") is
Filter.hideEmpty, wired end to end (sidebarFilters.jade/.js, consumed by
client/components/swimlanes/swimlanes.js). #2035 ("extended Filter feature
that will list up archived cards and cards in archived lists") is
Filter.archive, whose sidebar toggle re-subscribes to the board with the
archived flag set rather than only filtering client-side. Neither had a
regression test pinning that the wiring stays intact; this reads the actual
source for both and fails if either toggle, handler or consumer disappears.
Thanks to Sh0g0-1758 and blaisep and xet7 !
Fixes#567,
Fixes#2035.
filters active when switching boards.
Filter.userId (client/lib/filter.js) is a new SetFilter keyed the same way
models/cards.js already names the card-author field, reusing the exact
SetFilter/Filter API the existing member/assignee filters use - no new
filtering engine. A "Filter by creator" sidebar section lists the board's
active members the same way Member/Assignee already do.
config/router.js's board route used to call Filter.reset() (wiping every
filter) whenever the target board differed from the current one. It now
calls the new Filter.resetBoardScoped(), which only clears filters whose
values are scoped to the board being left (labels, custom fields,
dependency types, the advanced/list text filters) and leaves
member/assignee/creator/due-date/title filters in place, since user ids and
dates mean the same thing on every board. Every other Filter.reset() call
site (the sidebar's own Clear button, All Boards, Archive, Public, ...) is
unchanged.
Thanks to lukasz-krawczyk and jarohen-oc and xet7 !
Fixes#3681,
Fixes#1751.
Issue #1089 asked for "Link to this list", and reported the same fault
#6459 later named exactly: the list-more popup's link box read the
nonexistent {{ rootUrl }} template helper, so the box was always empty -
there was no working list link, and no swimlane link at all.
Commit e755b60b3 ("Link to a swimlane or a list, the way you can link to
a card.") already fixed this: models/lib/boardItemUrl.js builds a real
relative path, List#absoluteUrl/Swimlane#absoluteUrl resolve it through
Meteor.absoluteUrl(), and listHeader.js/swimlaneHeader.js's copy-link
handlers call it - confirmed by reading the current code, not just the
commit.
tests/listSwimlaneLinkRootUrlIssue1089.test.cjs pins this: the list and
swimlane copy-link handlers and absoluteUrl() implementations use the
real Meteor.absoluteUrl() API, and (negative) no .jade template or .js
helper anywhere in client/ still references a bare/broken rootUrl -
either the exact string reported in #1089 or a `rootUrl` template
helper, which never existed and was the bug.
Thanks to xet7 !
#2194 asked for a text-search rule condition combinable with other
triggers. WeKan's rules stay single-trigger/single-condition today -
combining several conditions in one rule with AND was already looked
at and explicitly deferred by #4294 (see TODO Later) - so this adds
ONE new standalone trigger type instead: "when a card's title or
description contains {value}", the same scope-down the #3092
advanced-filter trigger used.
A new pure module, models/lib/ruleTextContainsMatch.js, does a
case-insensitive substring test against a card's title/description;
server/rulesHelper.js (already wired to import and call it) evaluates
it the same way it already evaluates the advanced-filter trigger, on
card creation and the a-changedTitle/a-changedDescription activities.
This commit adds the missing pieces to complete that wiring: the pure
module itself, the card-triggers Add Rule UI row (cardTriggers.jade/
.js) with its text input, and tests/rulesTextContainsTrigger.test.cjs
pinning the match function, the trigger registration, the
rulesHelper.js wiring, the UI wiring and the i18n keys.
Thanks to sfahrenholz and xet7 !
Closes#2194,
Admin Panel / People, Board Settings and Member Settings each gain a
"Notification Settings" menu entry, right below Email in Admin Panel /
People. All three open the same reusable notificationSettingsPopup
template, letting notifications (tray/in-app and email, the two services
Notifications.notify already dispatches to) be turned on or off with the
same precedence the theme override already uses: Admin Panel default,
then Board override, then the member's own override.
models/lib/notificationSettings.js is a small pure module with the
resolution function (resolveNotificationSetting) and the notification-type
catalog; server/notifications/profile.js and server/notifications/email.js
now resolve the decision before adding to the tray or buffering an email,
so a disabled service is genuinely skipped rather than only hidden in the
UI. Settings.notifyDefaultTray/Email hold the admin default,
Board.notifyOverrideTray/Email the board override, and
profile.notifyOverrideTray/Email the member override; each is optional/
nullable so "unset" always falls through to the next level.
date-field range (#2075).
#3319 already sums a number-type custom field flagged
showSumAtTopOfList=true across a list's (optionally swimlane-scoped)
cards and shows it as a "∑ N" badge. #2075 asked for a broader list-level
summary: min/max for a number field, a range for a date field, and how
many cards have the field set at all. This extends that SAME mechanism -
the same per-field checkbox, the same badge area - rather than adding a
second configuration surface:
- models/lib/customFieldsSum.js gains numberFieldStats() (sum/min/max/
count-of-total, reusing the exact numeric-parsing rules of the existing
sumCustomFieldValues()) and dateFieldRange() (earliest/latest among the
cards, same count/total). Neither touches sumCustomFieldValues() itself.
- client/components/lists/listHeader.js's numberFieldsSum()/
hasNumberFieldsSum() now share their field/card lookup with the new
numberFieldsSumTooltip() (adds "(min–max, N/total)" to the sum badge's
tooltip, wordless so it needs no new i18n key) and the new
hasDateFieldsRange()/dateFieldsRangeLabel()/dateFieldsRangeTooltip() for
a date-type field flagged the same way - shown as an earliest–latest
badge instead of a sum, since summing dates has no meaning.
- listHeader.jade adds the date-range badge next to the existing sum
badge (both mini-screen and full layouts), and points the sum badge's
title at the new tooltip helper.
- One new i18n key, "date-range-of-fields", mirroring the existing
"sum-of-number-fields" tooltip label; min/max/count are numeric-only so
they need no new translatable words. Added to en.i18n.json and to all
245 other locale files - a direct translation for the ~65 base
languages covered by a curated dictionary (reused across their locale
variants), an English placeholder for the remainder per the
no-translation-anywhere-yet policy, to be filled the normal way via
releases/translations/fill-translations.mjs.
- tests/customFieldsSum.test.cjs: a #3319 regression test proving
sumCustomFieldValues()'s own result is untouched, plus coverage for
numberFieldStats() (sum/min/max, several flagged fields combined,
card-count-with-value, non-numeric values ignored, empty input) and
dateFieldRange() (earliest/latest, Date and ISO-string values, count,
an unparseable value ignored rather than corrupting the range, empty
input). node tests/customFieldsSum.test.cjs: 21/21 passed.
Thanks to rlach and xet7 !
Closes#2075,
tests/swimlaneWipLimitGroup.test.cjs covers listIdsForSwimlane
(models/lib/wipLimitGroupDecision.js), and the combined-count/over-limit
decision it feeds for #2380 (a WIP limit across a whole swimlane's lists),
proving the combined total is independent of any single member list's own
individual wipLimit, and that a list from a different swimlane is
unaffected.
convertChecklistItemToSubtask-title and checklistItem-linked-subtask
(en.i18n.json's new keys for the "Convert to subtask" checklist-item action,
#2422) translated directly into every other non-English locale file, in
en.i18n.json's key order, right after convertChecklistItemToCardPopup-title.
Thanks to javen9881 and xet7 !
A custom field with "Auto create field to all cards" (or "Always on
card") applied to the first card created via a list's quick-add form,
but was silent about it for any card created after: the automatic
fields were computed once, inline in addCardForm's onCreated, and the
form's own reset() unconditionally cleared that list back to [] instead
of recomputing it from the board's current custom-field definitions.
Any reset between two cards in the same session dropped the field
starting with the second card.
Both onCreated and reset() now call a shared
automaticCustomFieldsForCurrentBoard() helper, so the automatic fields
are (re)applied consistently rather than only once per template
lifetime.
Thanks to coleyon and xet7 !
Fixes#2392,
The Archive sidebar's card tab only ever showed the narrow shared minicard,
with nothing to click on - there was no `.js-minicard` handler in
sidebarArchives.js at all, so an archived card had no way to be opened beyond
that cramped preview. Clicking one now opens the SAME full card-detail popup
(`cardDetailsPopup` / `Template.cardDetails`) a normal board card already
opens, reusing the exact popupCardId/popupCardBoardId + Popup.open('cardDetails')
mechanism myCards.js and resultCard.js use for their own cross-context
minicards - not a parallel "archived card preview" component.
The normal card-detail action menu had no way to un-archive a card opened
this way: it hid "Archive" while a card was already archived but offered
nothing in its place. Both copies of the action menu (the canModifyCard one
and the read-only one) now show a "Restore" entry exactly where "Archive"
would be, calling the same `card.restore()` mutation the Archive sidebar's
own Restore link already uses, with the same target-list fallback popup for
a card whose list was itself archived or deleted.
creation it reuses.
#2209 (a 2019 follow-up to #2165's template-feature checklist) asked for
"create template from element" - creating a template directly from an
existing board/list/card, rather than only from scratch. WeKan's own
"insert a card FROM a template" flow (searchElementPopup) already existed,
but nothing did the reverse: turning an existing card INTO a template.
The card menu now offers "Save as Template" beside "Copy Card". It posts
to a new saveCardAsTemplate server method that copies the card into the
user's own "Card Templates" swimlane (creating the personal Templates
board on first use, exactly as the existing default-board-template flow
already does), marking the copy type: 'template-card' so it behaves as a
template rather than an ordinary card.
The lazy per-user Templates board creation used to live only inline in
the ensureTemplatesBoard Meteor method; it is now exported as
ensureTemplatesBoardForUserId (server/models/users.js) so this new method
can call it directly server-side instead of duplicating the board/
swimlane setup.
#2209's other two sub-items were checked and are already handled:
"cards don't appear in swimlanes if the general swimlane is deleted"
(#1959) already has thorough startup-rescue coverage in
server/lib/schemaUpgradeSteps.js (the "swimlane-structure" step) plus
regression tests in tests/schemaUpgradeSteps.test.cjs, and "templated
users" was explicitly out of scope per the issue's own text.
Thanks to andresmanelli and xet7 !
The due-date badge (card detail and minicard) showed only the formatted
date - no relative countdown, contrary to what the badge's own title
text suggested. dueCountdown() (client/lib/dueDateColor.js) is a pure
day-count helper, sharing its "now" comparison with the existing
dueDateClass() so the countdown and the badge's colour always agree;
cardDate.js's new dueCountdownText() turns it into translated text and
both cardDueDate and minicardDueDate now show it in showDate() (visible
text) and showTitle() (hover), e.g. "Jun 15 (3 days left)" / "Jun 15 (2
days overdue)" / "Jun 15 (Due today)". A completed due date (one with an
end date set) keeps just the plain date - there is nothing left to count
down. Received/start/end date badges are untouched; they use their own
showDate()/showTitle() overrides on the same shared dateBadgeBody markup.
Adds due-today/due-days-left/due-days-overdue to en.i18n.json (right
after card-due-on) and translates them into all 245 other locale files,
keeping the %s day-count placeholder intact everywhere.
Thanks to javen9881 and xet7 !
Closes#2424,
WeKan only ever sent email; there was no way to receive it, so replying to a
notification email went nowhere. This adds the webhook-based half of #2414 -
not an IMAP-polling mail client, which would need a running mailbox,
credentials and a polling loop the self-hoster would have to operate. Instead
a self-hoster points a mail provider's inbound-parse webhook (Mailgun Routes,
SendGrid Inbound Parse, Postmark inbound - documented in
docs/Features/Email/Reply-By-Email.md) at a new POST /api/inbound-email.
Every outbound notification email's Reply-To now carries
reply+<cardId>-<hmac>@<domain> (server/lib/inboundEmailReplyToken.js), the
HMAC keyed by INBOUND_EMAIL_HMAC_SECRET so it cannot be forged or guessed.
The webhook verifies that token, resolves the card, strips the reply's quoted
text (server/lib/inboundEmailQuoteStrip.js), matches the sender's address to
an existing WeKan user (server/lib/inboundEmailUserMatch.js - no match is
rejected, never an anonymous comment), and inserts a CardComments document.
Unauthenticated by design, so every rejection (bad/forged token, unmatched
sender) is logged via securityLog under the new authn.inbound-email catalog
key, wrapped so logging can never break the guard.
Both INBOUND_EMAIL_HMAC_SECRET and INBOUND_EMAIL_DOMAIN are opt-in; unset
(the default), no Reply-To is added and existing installs are unchanged.
Thanks to vasyugan and xet7 !
Closes#2414,
#2335 reported that opening a card to edit it resets an active board
filter. Filter (client/lib/filter.js) is a plain module-level singleton,
not keyed by route or Session, and card open/close
(client/components/cards/cardDetails.js) never calls Filter.reset() or
any other filter-clearing method - it only ever calls
Filter.addException() to keep an affected card visible. The only three
Filter.reset() call sites in the client are explicit user actions: the
"clear filter" button, the sidebar "clear all" button, and the `x`
hotkey. So the filter does not reset today; what can look like a reset
is the filtered list reactively dropping a card that no longer matches
the active filter after an edit, which is correct filtering behavior.
tests/filterPersistsOnCardOpen2335.test.cjs pins this: no card-open/close
code path calls Filter.reset()/clear, and every Filter.reset() call site
in client/ and imports/ is one of the three known, explicit actions.
Copy/link rule actions (#4160, #3235), email attachments (#3948),
custom-field rule values (#3195), GitLab sync (#2698), a scheduled
due-date rule action (#4278) and more template variables (#3815) are
each a real feature or need external infrastructure this sandbox
cannot stand up, so they are recorded with their reasons rather than
forced.
Copy/link rule actions (#4160, #3235), email attachments (#3948),
custom-field rule values (#3195), GitLab sync (#2698), a scheduled
due-date rule action (#4278) and more template variables (#3815) are
each a real feature or need external infrastructure this sandbox
cannot stand up, so they are recorded with their reasons rather than
forced.
wekan/wekan#2419: a card description/comment containing task-list syntax
rendered the literal text "<input disable=\"\" type=\"checkbox\"/> Task"
instead of a checkbox, because the markdown-it renderer had no task-list
extension (so it never emitted an <input> at all) and the sanitizer
forbade the input tag outright, so even a typed-in <input> would have
been stripped.
Add a small markdown-it core rule that turns a leading "[ ]"/"[x]"/"[X]"
marker on a list item into a disabled <input type="checkbox">, and allow
that exact shape through secureDOMPurify.js: only type="checkbox", and
never one carrying name/value/form/formaction, so nothing but a plain
checkbox can reach the page. The checkbox is left disabled - click-to-
toggle would mean mapping a rendered click back into the raw markdown
source and saving it, a separate, larger feature from this rendering fix.
Thanks to rodrigocipriani and xet7 !
Fixes#2419,
Adds a board-wide Boards.allowsSwimlaneNameOnMinicard toggle (default
false), a Card Settings row for it (already landed in
client/components/sidebar/sidebar.jade/.js and models/boards.js via a
concurrent commit), and the minicard label itself: gated on the board
flag, resolving the swimlane reactively via
ReactiveCache.getSwimlane(card.swimlaneId), styled like the existing
list-name label. tests/minicardSwimlaneNameOnMinicard.test.cjs pins the
default, the Card Settings row, and that the minicard only renders the
label when enabled.
Thanks to JB_Pollard and xet7 !
Closes#2426,
The "add member" rule action's acting-user option (issue #2522 - "add
whoever just moved the card as a member") landed on main missing its
shared module: server/rulesHelper.js and cardActions.js already import
RULE_ACTING_USER_SENTINEL/resolveActingUserId from
/models/lib/ruleActingUser, but that file was never committed, breaking
the import on main. It also landed without the actual UI button that
saves the sentinel action.
models/lib/ruleActingUser.js resolves "who triggered this rule" from
activity.userId - the exact same source buildRuleVars() already uses for
the {username} template variable (#3304/#3301) - so both call one shared
function instead of two implementations of the same concept.
cardActions.jade gets the missing trigger button, wired to the existing
js-add-actinguser-member-action handler in cardActions.js.
tests/ruleAddMemberActingUser.test.cjs pins the sentinel resolution, that
rulesHelper.js and buildRuleVars() both call the one shared resolver (with
a negative, whole-tree source-pattern check that no other file
re-implements the same activity.userId shape), that the ordinary
fixed-member path is unaffected, the client/jade wiring, and that every
locale file has a real (non-English-placeholder) translation of the new
label. tests/ruleRemoveMemberAction.test.cjs and
tests/rulesApiTriggerNormalize.test.cjs are updated for the addMember
block's new if/else shape around the sentinel check.
Thanks to arisjr and xet7 !
Closes#2522,
WeKan already limits work-in-progress per list (models/lists.js wipLimit),
but a workflow that splits "in progress" into several columns (e.g. three
middle columns together) had no way to cap the total across them - only
each column on its own. Boards.wipLimitGroups adds a small array of
{_id, name, listIds, limit, enabled} groups, settable from a new "WIP
Limit Groups" panel in Board Settings (reusing the existing Swimlane/
List/Card settings popup pattern), where 2+ of the board's lists are
picked to share one combined numeric limit.
models/lib/wipLimitGroupDecision.js is the pure arithmetic behind it -
combinedWipLimitGroupCount sums the current card count across a group's
member lists, isWipLimitGroupExceeded mirrors the per-list "exceeded"
threshold (value < count), and isListInExceededWipLimitGroup answers
whether a given list belongs to any group that is currently over its
own shared limit, independent of that list's own individual wipLimit.
The list header reuses the exact same `.highlight` over-limit styling
the per-list WIP counter already uses (client/components/lists/list.css)
rather than a second visual language: every list that is a member of an
exceeded group gets its title highlighted, not only the list that
happens to be over on its own.
Admin Panel -> Settings -> Visibility gets a new "External Issue Tracker
Autolink" group: a token prefix (e.g. "#") and a URL template containing
"{number}" (e.g. https://issues.example.com/browse/PROJ-{number}). When both
are set, a bare "<prefix><digits>" token found in card descriptions/comments
is rendered as a link to that external tracker, the same idea as the
Mattermost autolink plugin. Either field left empty keeps the feature off.
WeKan does not autolink bare "#NNNN" to its own cards anywhere - confirmed by
reading the whole markdown pipeline (packages/markdown) and every client
template before adding this, per models/lib/externalLinkAutolink.js's own
comment - so there is nothing internal for this to collide with. It stays
safe regardless: off by default, and it never rewrites a token that already
sits inside an existing markdown link target or an href="..." attribute.
models/lib/externalLinkAutolink.js is the pure, unit-tested matching/URL-
building function; packages/markdown/src/template-integration.js cannot
import app code, so it carries its own small mirror of the same algorithm,
bridged from the setting via a ReactiveVar the same way alwaysShowCodeAsText
already is, kept in sync by client/components/main/editor.js.
server/publications/settings.js publishes the two new fields - a setting a
template reads that the publication does not send always renders empty and
makes "Save" look like it did nothing.
Adds the "external-link-pattern"/-description/-prefix/-url keys to
en.i18n.json and all 245 other locale files, translated directly (no
placeholder service), preserving the "{number}" placeholder untouched in
every language. tests/externalLinkAutolink.test.cjs covers the pure function
(matching, URL building, no-op when unconfigured, the existing-link
collision guard), the settings/publication/bridge wiring, i18n key placement
and placeholder preservation across every locale file, and confirms by
source inspection that no internal #NNNN-to-card autolinker exists anywhere
in the tree.
Concurrent edits to server/rulesHelper.js's sendEmail block in this shared
checkout dropped the "Description: ..." footer line added earlier for
#2713 (the description sits right next to the pre-existing "Card:"/"Link:"
lines from #3301, so it merged awkwardly). Restoring it: the sendEmail
action now appends the card's description automatically again, same as its
title and link, guarded the same way (only when non-empty).
Thanks to kabi178 and xet7 !
Apple's Sign in with Apple is OIDC-compatible, so it works through Wekan's
existing generic OAuth2/OIDC client - except its "client secret" is not a
static string: it must be a short-lived JWT the server signs itself (ES256),
using a private key downloaded from Apple's developer portal. Every other
generic OAuth2 provider Wekan supports (Keycloak, Authelia, Nextcloud, ...)
keeps sending its static OAUTH2_SECRET unchanged.
models/lib/oauth2ClientSecretJwt.js mints that JWT using only Node's built-in
crypto module (no new dependency: ES256 signing with IEEE-P1363 signature
encoding has been supported since Node 12). It is opt-in: when
OAUTH2_SECRET_JWT_KEY_PATH is unset (the default, and every existing
provider's configuration), maybeGenerateOauth2ClientSecretJwt() returns null
and packages/wekan-oidc/oidc_server.js falls back to the static OAUTH2_SECRET
exactly as before.
Apple's other quirk - it returns the user's name only on the very first
authorization - needs no special-casing: Accounts.onCreateUser
(server/models/users.js) already copies the OIDC fullname/email claims into
the user's profile only once, at account creation, and never overwrites them
on later logins (Meteor's updateOrCreateUserFromExternalService only touches
services.oidc.* for a returning user, not profile.*).
docs/Features/Login/Apple.md documents Apple's endpoints and the new env
vars, mirroring the Keycloak/Authelia docs pattern.
Thanks to xet7 !
Closes#2458,
Mirrors tests/rulesAssigneeTrigger.test.cjs's pattern: proves the 4
activityTypes are registered with the right matchingFields, that the
existing Cards.before.update timing-field hook is what feeds them (SET
only, never an $unset clear), that the matcher fires/doesn't fire on the
right board and doesn't cross-fire between the 4 date fields or on an
unrelated activity, that the Rules UI wires up all 4, and that every
locale file got a real (non-English) translation for the 4 new keys in
the right position.
Thanks to justinr1234 and xet7 !
Closes#2474,
A card description or comment containing a plain, pasted URL to another
WeKan card ("/b/<boardId>/<slug>/<cardId>", optionally with the
#comment-/#activity- fragment from #4757) rendered as a raw, unlabeled
link. models/lib/cardUrlAutolink.js is a pure parser/rewriter that finds
such URLs in text and replaces one not already inside a markdown/HTML
link with "[title](url)", given a title resolver - mirrored inline in
packages/markdown/src/template-integration.js (that package cannot
import app code, the same reason externalLinkAutolink.js is mirrored
there for #3069) and run in the 'markdown' Blaze helper just before
markdown-it's own render.
The resolver is wired in client/components/main/editor.js's existing
Meteor.startup as Markdown.resolveCardTitle, a plain function calling
ReactiveCache.getCard(cardId). Because that lookup is itself a reactive
Tracker dependency read inside the markdown helper's own reactive
computation, the rendered title updates automatically if the target
card is later renamed, and resolves to nothing - leaving the bare URL
untouched - for a card this client's Minimongo has not received: a
deleted card, or one on a board the current viewer cannot see. That
fallback is exercised directly with a mocked resolver in
tests/cardUrlAutolink.test.cjs, alongside URL parsing (boardId/slug/
cardId, fragments, rejecting unrelated links) and the "already inside a
link" no-double-linking guard.
Thanks to justinr1234 and xet7 !
Closes#2453,
server/triggersDef.js now registers the 'a-dueAt'/'a-startAt'/'a-endAt'/
'a-receivedAt' activityTypes that models/cards.js's setDue/setStart/
setEnd/setReceived already log via server/models/cards.js's timing-field
hook (the same activity the due-date-change-count feature, #6081, already
reads). This wires those existing activities into the Rules matcher so a
rule can trigger "when the due/start/end/received date is set or changed",
reusing the TriggersDef-driven matching machinery every other trigger
already uses.
Thanks to justinr1234 and xet7 !
Closes#2474,
The card detail view and minicard already rendered a card's accumulated
spent-time badge (and its overtime indicator) unconditionally once time was
logged, but there was no way to turn it off, and reaching it in the first
place meant the card's hamburger/context menu. Add allowsSpentTime /
allowsSpentTimeOnMinicard board fields (both default true, so no existing
board's display changes) and a matching Card Settings row - the same
"Show on card"/"Show on minicard" pattern already used by
allowsReceivedDate/allowsReceivedDateOnMinicard - so an admin can hide it
per board.
Thanks to matrixes and xet7 !
Closes#2530,
Planyway-style: shows due/start/end/received dates for cards across
every board the current user belongs to, not just the currently open
board, right below Calendar in the Board View menu.
Reuses the single-board Calendar view's FullCalendar rendering as-is
and #4223 Bigboard's all-boards membership query/subscription pattern,
prefixing each event with its board's title so entries stay
distinguishable. Cross-board drag-to-reschedule is out of scope here;
the view is read-only and the single-board Calendar's own drag
handling is unaffected.
Thanks to justinr1234 and xet7 !
Closes#2469,
The checklist's own action popup (checklistActionsPopup) had reset,
hide-checked, hide-all and export/edit-as-text actions but no way to bulk
check or uncheck every item at once - #4218's "Edit as text" only offers an
indirect workaround (replace every "[ ]"/"[x]" by hand). Checklists.
checkAllItems()/uncheckAllItems() already existed as model helpers used by
the Rules automation (server/rulesHelper.js), so this wires the same two
methods to new menu entries, and extracts the item-selection logic they
share into a pure, unit-testable helper (models/lib/checklistBulkCheck.js).
Thanks to justinr1234 and xet7 !
Closes#2473,
Both issues describe the same gap from opposite directions: #3249 is the
board whose creator left leaving nobody able to manage it, and #2413 asks
for site admins to be able to view/change permissions on any board. The
isBoardAdminOrSiteAdmin/allowIsBoardAdminOrSiteAdmin helpers and the
Boards.allow update/remove wiring landed for #3249 already grant exactly
what #2413 asked for, so tests/boardAdminOrSiteAdmin.test.cjs is annotated
to say so explicitly.
Thanks to JackNWeems and xet7 !
Fixes#2413,
server/models/users.js's new anonymizeUser Meteor method (already committed)
requires models/lib/userAnonymization.js for its pure decision/update-shape
logic, matching models/lib/userDeletionCleanup.js's split for removeUser -
that module and its test were still untracked, so the require was pointing
at nothing. Add both now.
Thanks to Akuket and xet7 !
Closes#2731,
#2713 asked for two things.
Editing a rule used to mean delete it and rebuild it from scratch, losing
its position and its identity. rulesList's rule row gets a second "Edit
trigger/action" button next to the existing title-rename pencil, opening
the same trigger/action wizard used to create a rule (rulesMain.js /
rulesTriggers / rulesActions and the board/card/checklist/mail action
templates), pre-filled with the rule's current title. A new server method,
rules.updateRule (server/rulesButton.js), mirrors rules.createRule's
authorization and cross-board destination checks but REPLACES the existing
trigger/action documents in place (full-document update by their existing
_id, not remove+insert), so the rule keeps its own _id, and its trigger/
action keep theirs, across an edit. Every action-template click handler
that used to call rules.createRule or insert Triggers/Actions/Rules
directly now goes through one shared helper,
client/components/rules/rulesSaveHelper.js, which picks create vs. update
based on whether the wizard was opened to edit an existing rule.
The "send an email" rule action already appended the card's title and a
link to it automatically (#3301), even when the user's own template used
none of the {card}/{cardLink} tokens; it did not do the same for the card's
description. server/rulesHelper.js now appends "Description: ..." to the
footer alongside the existing title/link lines, using the vars.description
value buildRuleVars already computed.
Actually attaching the card's FILE ATTACHMENTS to the outgoing email is
deferred - see CHANGELOG TODO Later. Every WeKan email today goes through
either Meteor's `Email.sendAsync`/`EmailLocalization.sendEmail`, which take
{ to, from, subject, text }, with no `attachments` parameter anywhere in
this codebase's call sites; wiring a real file through would need the
mailer wrapper itself to grow attachment support and code to read the file
back out of whichever storage backend (local disk / GridFS / S3) holds it,
which is mailer-level scope well past this rule action.
tests/ruleUpdateInPlace.test.cjs pins rules.updateRule's authorization,
its RuleBleed cross-board guard, and - the part that actually makes it an
edit rather than a second create - that it keeps the rule/trigger/action
_ids stable, including a logic-level round trip against a small in-memory
mock proving a changed actionType does not leave the old type's fields
behind. tests/ruleEmailIncludesDescription.test.cjs pins the new
description line, guarded the same way the existing title/link lines are
(only appended when non-empty).
tests/ruleCardActionSchema.test.cjs (#6630's guard, that desc lives on the
Action document and never leaks onto the Rule document) is updated for the
new saveRuleTriggerAction call shape.
Thanks to kabi178 and xet7 !
#2713 asked for two things.
Editing a rule used to mean delete it and rebuild it from scratch, losing
its position and its identity. rulesList's rule row gets a second "Edit
trigger/action" button next to the existing title-rename pencil, opening
the same trigger/action wizard used to create a rule (rulesMain.js /
rulesTriggers / rulesActions and the board/card/checklist/mail action
templates), pre-filled with the rule's current title. A new server method,
rules.updateRule (server/rulesButton.js), mirrors rules.createRule's
authorization and cross-board destination checks but REPLACES the existing
trigger/action documents in place (full-document update by their existing
_id, not remove+insert), so the rule keeps its own _id, and its trigger/
action keep theirs, across an edit. Every action-template click handler
that used to call rules.createRule or insert Triggers/Actions/Rules
directly now goes through one shared helper,
client/components/rules/rulesSaveHelper.js, which picks create vs. update
based on whether the wizard was opened to edit an existing rule.
The "send an email" rule action already appended the card's title and a
link to it automatically (#3301), even when the user's own template used
none of the {card}/{cardLink} tokens; it did not do the same for the card's
description. server/rulesHelper.js now appends "Description: ..." to the
footer alongside the existing title/link lines, using the vars.description
value buildRuleVars already computed.
Actually attaching the card's FILE ATTACHMENTS to the outgoing email is
deferred - see CHANGELOG TODO Later. Every WeKan email today goes through
either Meteor's `Email.sendAsync`/`EmailLocalization.sendEmail`, which take
{ to, from, subject, text }, with no `attachments` parameter anywhere in
this codebase's call sites; wiring a real file through would need the
mailer wrapper itself to grow attachment support and code to read the file
back out of whichever storage backend (local disk / GridFS / S3) holds it,
which is mailer-level scope well past this rule action.
tests/ruleUpdateInPlace.test.cjs pins rules.updateRule's authorization,
its RuleBleed cross-board guard, and - the part that actually makes it an
edit rather than a second create - that it keeps the rule/trigger/action
_ids stable, including a logic-level round trip against a small in-memory
mock proving a changed actionType does not leave the old type's fields
behind. tests/ruleEmailIncludesDescription.test.cjs pins the new
description line, guarded the same way the existing title/line lines are
(only appended when non-empty).
tests/ruleCardActionSchema.test.cjs (#6630's guard, that desc lives on the
Action document and never leaks onto the Rule document) is updated for the
new saveRuleTriggerAction call shape.
Thanks to jvavassori and xet7 !
#3050: cards within a list are always rendered in the manual drag `sort`
order, with no way to bring the highest-voted cards to the top without
reordering them by hand.
The existing board-wide "Sort" popup (`cardsSortPopup`, already offering
due date / title / created date) gets a new "Sort by votes" entry -
extending it is the natural, minimal fit since it is already the one
alternate-sort mechanism WeKan has for cards, rather than building a
separate per-list toggle or a new multi-criteria picker.
Vote score (positive votes minus negative votes) is not a real Mongo
field, so it cannot be expressed as a Mongo sort spec the way due date/
title/created date are. `{ votes: -1 }` is used as a marker only:
`cardsWithLimit()` (client/components/lists/listBody.js) recognizes it,
fetches the window in the underlying manual `sort` order, and re-sorts
the resulting array in JS by vote score - a pure DISPLAY-order change.
The manual `sort` field on each card is never touched, so switching the
mode back off (or the plain "Sort" reset) restores the exact manual
drag order.
models/lib/voteSortCards.js extracts the comparator as a plain,
Meteor-free module (mirrors models/lib/boardSortReorder.js and
models/lib/sortCardsByTitle.js) so the scoring and ordering rules are
unit-testable: highest vote score first, a card with no votes scores 0
and sorts last, and ties (including two zero-vote cards) keep their
relative manual-sort order via a stable sort - proven in
tests/voteSortCards.test.cjs.
Thanks to xet7 !
Closes#3050,
Pins the pure hasUnreadComments() decision (comment-after-last-view,
never-viewed-with-a-comment, zero comments, malformed timestamps), that
profile.cardLastViews reuses the existing collapsedCardSections shape rather
than a new tracking mechanism, that opening a card is what clears it, and
that the minicard highlight is a class (not a background fill that would
hide a label swatch).
Thanks to H4usi and xet7 !
Closes#3078,
The previous commit's pathspec commit picked up an unrelated in-progress
edit to the spent-time section (gating it on currentBoard.allowsSpentTime)
that happened to be sitting in the same file in the shared working tree.
That edit belongs to different, unfinished work and had no test or
CHANGELOG entry of its own; restore the card-details-item-spent block this
commit's Move-card checkbox change should not have touched.
#2886: clicking a label filter chip only ever toggled between unfiltered
and filtering FOR that label. Filter.labelIds now has a companion
Filter.excludedLabelIds SetFilter (same API/shape), and a new
Filter.toggleLabelFilter(labelId) cycles a label through three states:
not in either set -> added to labelIds (include) -> moved to
excludedLabelIds (exclude) -> removed (back to unfiltered).
Filter._getMongoSelector() merges the exclusion into the existing
labelIds selector ({$in, $nin}) rather than a separate ignored key, so a
card carrying an excluded label is filtered out even when it also
matches an included label - exclusion wins over inclusion. An
exclude-only filter (no included label) is also handled: isActive() and
the filterSelector-push condition both check excludedLabelIds, and
reset() clears it too.
sidebarFilters.js's 'click .js-toggle-label-filter' handler now calls
Filter.toggleLabelFilter() for a real label chip, keeping the existing
plain two-state Filter.labelIds.toggle() only for the special "no label"
pseudo-entry (data-filter-id="__none__"), which is out of scope for this
three-state cycle. sidebarFilters.jade gives an excluded chip a distinct
"excluded" class (struck-through text via sidebar.css) plus a fa-ban icon
tooltipped with the new filter-label-excluded i18n key, alongside the
existing fa-check used for an included chip.
Scoped to labels only, matching the issue's exact wording - members, due
dates and the other filter types keep their existing two-state toggle in
this pass; the same three-state treatment could be added to them later if
wanted.
tests/labelFilterThreeState.test.cjs drives the real client/lib/filter.js
under plain `node` (via tests/helpers/meteorStubLoader.mjs, an ESM loader
hook stubbing only the Meteor packages/modules filter.js imports) rather
than reimplementing the logic, and pins: the exact three-click cycle in
order (unfiltered -> included -> excluded -> unfiltered), that the cycle
repeats and that two labels cycle independently, and the card-matching
predicate - an excluded-only card is filtered out, an excluded label
wins over an included one on the same card, and an exclude-only filter
(nothing included) still filters correctly.
Thanks to bennyandresen and xet7 !
Closes#2886,
#808 added the in-app Calendar view; #2836 ("CalDAV or iCal Support") asked
specifically for calendar EXPORT/SYNC via iCal or CalDAV, which did not exist
- only a one-way .ics IMPORT (icsImport.js, #6323) was in the codebase, with
a comment pointing to a separate external project for export.
Adds a new GET /api/boards/:boardId/calendar.ics route (models/export.js)
that streams a subscribable, read-only iCalendar feed of a board's cards:
one VEVENT per Received / Start-End span / Due date, the same four dates the
Calendar view already draws. Public boards need no token; private boards
authenticate the same way every other export route does (?authToken=, or a
logged-in session), and reuse Exporter.canExport()/_scopedCardSelector() so
the feed honours the same board-visibility and swimlane/list scoping as the
JSON/CSV/PDF exports. The ICS text itself is built by a new pure, dependency-
free module, models/lib/icalExport.js (mirrors icsImport.js's style), so it
is unit-testable without Meteor and reusable elsewhere.
The board Export popup gets a new "iCal" group with one link, built through
the existing exportUrl()/EXPORT_FORMAT_GROUPS table so it carries the same
authToken/scope handling as every other export format.
Deliberately EXPORT only, one-way, read-only: full CalDAV is a stateful,
two-way sync PROTOCOL with its own server (PROPFIND/REPORT, ETags,
collections), which is a much larger feature than a dates feed. Every
calendar client that can "subscribe to a URL" - Google Calendar, Apple
Calendar, Thunderbird, Outlook - reads a plain .ics feed like this one
directly; CalDAV is not needed for that.
Thanks to xet7 !
Closes#2836,
Issue #3058 asked for two-factor authentication on WeKan's own
username/password login, not through a third-party OAuth provider. Added
Meteor's official accounts-2fa package (MIT, part of the meteor/meteor
monorepo, same publisher as accounts-password already in use) instead of
hand-rolling TOTP.
A new "Two-Factor Authentication" section in the member menu
(client/components/users/userHeader.jade/.js) calls
Accounts.generate2faActivationQrCode to show a QR code plus a manual-entry
secret, and Accounts.enableUser2fa/disableUser2fa to finish enabling or to
turn it off; Accounts.has2faEnabled drives which of those is shown. All
TOTP secret generation and code verification is done by accounts-2fa
itself - WeKan only renders what it returns and calls its documented
functions.
On the sign-in form (config/accounts.js, client/components/main/layouts.jade),
a normal Meteor.loginWithPassword failure with error.error ===
'no-2fa-code' now shows a second "enter your 6-digit code" step instead of
a generic error, and resubmits via Meteor.loginWithPasswordAnd2faCode -
accounts-2fa's own login method for this case. The decision of which step
to show is a pure function (imports/lib/twoFactorAuthLoginDecision.js),
unit-tested in tests/twoFactorLoginState.test.cjs without a running Meteor
server. wekan-accounts-lockout already anticipated this: its
loginFailureDecision.js already treated 'no-2fa-code' as a non-countable
step so 2FA logins are never mistaken for brute-force attempts.
Scope: opt-in, per-user TOTP only, as the issue asked - no backup codes, no
SMS, no admin-enforced 2FA in this pass; accounts-2fa does not offer any of
those out of the box either.
This environment has no Meteor CLI, so `meteor add accounts-2fa` and the
login UI could not be exercised end-to-end here; the package was verified
against its published source (packages/accounts-2fa/package.js, version
3.1.0) and docs.meteor.com instead, and added to .meteor/packages/versions
by hand.
New UI strings (twoFactorAuth-*/twoFactorCode-*) were added to
en.i18n.json and translated into the ~100 locales WeKan already had
existing coverage for to translate from; the remaining locale files keep
the English source as a placeholder pending translation, reported by
node releases/translations/fill-translations.mjs --missing.
Thanks to r0bbie and xet7 !
Closes#3058,
#2719: moving a card to a different board/list now offers "Leave a link at
the original location" in the Move card popup. Checked, the move still
happens as normal and a linked-card mirror (the existing
Cards.helpers().link() mechanism from #4281's "Link to board" action) is
created at the card's original board/swimlane/list, pointing at the (now
moved) card. Unchecked - the default - nothing changes from a plain move.
The original board/swimlane/list are captured from the card before
card.move() runs, and card.link() is called with them afterwards, so the
mirror is created after the destination update, using the same picker
(cardDestinationPicker) Move/Copy/Link already share.
Thanks to superlou and xet7 !
Closes#2719,
A custom field marked Admin only has its value hidden from - and cannot be
set by - a non board-admin board member: not on the card detail view, not on
the minicard, not in the card's "assign a custom field" popup list, and not
through the setCardCustomFieldCheckbox/setCardCustomFieldCurrency Meteor
methods or a direct client write of customFields.<index>.value. The toggle
itself, in the custom-field definition editor, is only rendered for and only
writable by a board admin (CustomFields.allow's update/insert rules now check
board.hasAdmin() specifically for the adminOnly field, on top of the existing
write-access check every other field edit already requires).
models/lib/customFieldsWD.js gets a small pure filterAdminOnlyDefinitions()
helper so the gate has one tested choke point: models/cards.js's
customFieldsWD() - shared by both the card-detail and minicard templates -
filters admin-only definitions out before matching them to a value, and
client/components/cards/cardCustomFields.js reuses the same helper for the
popup's field list.
Thanks to CarloRampini and xet7 !
Closes#3141,
A template-container board is a regular board with a special type, so it
already gets normal board membership - adding another user as a board
member of it is the existing, generic sharing mechanism, exactly like
sharing any other board, and server/publications/boards.js's
boardTemplates publication already lists any template-container board a
user is a member of, not only ones they personally created.
The gap was the "apply a template" picker (Template.searchElementPopup,
opened by the card/list/swimlane/board "from template" buttons in
client/components/lists/listBody.js): it was hard-wired to only the
current user's own profile.templatesBoardId, so a template board shared
by another member never appeared there even though it already showed up
in the All Boards "Templates" view. The picker now also subscribes to
boardTemplates and offers any OTHER template-container board the user is
a member of in a dropdown, defaulting to the user's own board as before.
Thanks to ADDAH-temp and xet7 !
Closes#2684,
#3136: Users.inviteUserToBoard (server/models/users.js) only ever sent an
invitation email. Board membership/watcher changes already fan out through
Notifications.notify(user, title, description, params) - the same helper
server/models/activities.js calls for card assignment, due dates, mentions
and every other activity-driven notification, reaching both the email
service and the in-app notification bell - but an invite itself never went
through it.
inviteUserToBoard now also calls Notifications.notify(user, 'push-invite-title',
'push-invite-text', params) with the same params object built for the
invitation email, right after the email is sent. It is guarded by
`!isNewUser`: a brand-new invitee created from an email address with no
matching WeKan account has no established notification target yet, so they
stay email-only, exactly as before, with no error. The push call has its own
try/catch so a failing notification service can never break the invite.
Added push-invite-title/push-invite-text to en.i18n.json and every other
locale file, reusing each locale's own already-translated
email-invite-subject/email-invite-text wording (the only existing invite
wording to draw a style from), so every locale ships a real translation
immediately - no English placeholders except the en-* regional variants,
which are English by design.
Added tests/boardInvitePushNotification.test.cjs: a source-inspection
regression test (inviteUserToBoard is a full Meteor method and cannot run
outside a Meteor server) pinning that the fix reuses the exact
Notifications.notify(user, title, description, params) helper/signature
already used elsewhere - exactly one call site, not a second
implementation - guarded by `if (!isNewUser)`, wrapped in its own try/catch,
with the email send left unconditional, and that every locale file carries
the two new keys with the same placeholder tokens as their email
counterparts.
Thanks to CondensedTea and xet7 !
Closes#3136,
There was no way to tell at a glance which cards had new comments since the
user last looked (#3078). Add a per-user, per-card last-viewed timestamp
(Users profile.cardLastViews, same shape as the existing
profile.collapsedCardSections) set whenever the user opens a card's detail
view, and a pure, tested decision (models/lib/unreadComments.js) that flags
a card as unread when it has a comment created after that timestamp, or any
comment at all when the card was never opened. The minicard shows a subtle
inset highlight (minicard-unread-comments) and a tooltip when flagged, and
opening the card clears it.
Thanks to H4usi and xet7 !
Closes#3078,
A comment's Reply link (added earlier for #5907) let a reply be posted
against ANY comment, including another reply, so clicking Reply enough
times nested comments arbitrarily deep. For #3011, a reply now attaches
to a reply's own parent instead of the reply itself - resolveParentId()
(models/cardComments.js) makes that decision once, is unit tested, and
is applied both when the client opens the composer (so the "In reply
to ..." banner already names the right comment) and again in a
CardComments.before.insert hook server-side, so the cap holds no
matter how a comment is inserted.
Replies also now render directly under their top-level parent instead
of interleaved by date with unrelated comments: groupCommentsByThread()
(imports/lib/commentThreading.js) reorders the already-sorted flat list
the comments template already used, with no schema or query change.
The "Replying to <author>" indicator on the composer reuses the
existing, already fully translated comment-in-reply-to string plus the
parent comment's author name, rather than adding a new i18n key that
would need translating across every locale file for a small wording
difference.
Added tests/commentReplyFlattening.test.cjs (the one-level cap, both
the client and server wiring) and tests/commentThreadGrouping.test.cjs
(grouping, including the regression cases: a flat list of only
top-level comments is unchanged, and a comment whose parent was
deleted still renders as top-level rather than being dropped).
Thanks to FuXXz and xet7 !
Closes#3011,
.swimlane's unconditional `overflow: auto` made every swimlane row its own
CSS scroll container on both axes, so `.list.list-sticky-header
.list-header`'s `position: sticky` (from #3847) stuck within that row's own
box instead of the real, page-level vertical scroll on `.board-canvas` -
list titles still scrolled away when scrolling down through swimlane rows.
`.swimlane` keeps `overflow-x: auto` for its row of lists but no longer
captures the vertical axis (`overflow-y: visible`), so the same toggle now
also pins headers correctly in the Swimlanes view. No second mechanism was
added; #3847's single `stickyListHeaders` toggle and CSS rule are reused.
Thanks to mikesutton and xet7 !
tests/labelTextVisibility.test.cjs pins the board-level
Boards.showLabelText setting (with its per-user override) that already
resolves#2561: a board-level toggle to hide label text on minicards,
leaving only the colour bars, the same request #4256 made and this suite
already covers.
Thanks to javen9881 and xet7 !
Fixes#2561,
Add a nullable labels.$.dueAt field to the board schema (models/boards.js),
unset by default so every existing label and board is unaffected. The
existing label create/edit popup gets a "Due Date" input wired through
Boards.addLabel/editLabel's new trailing dueAt argument; editLabel unsets it
explicitly when cleared. The labels list shows the date next to a label when
set. A "milestone" is then a label with a due date, and filtering cards by
that label is the existing label filter - no new Milestone object or filter
UI needed.
Thanks to locnide and xet7 !
Closes#2802,
tests/subtaskSwimlaneInheritance2732.test.cjs pins the existing behaviour
in server/models/cards.js's addSubtaskCard: it looks up the parent card's
own swimlane, reuses the destination subtasks board's swimlane whose
title matches it, and only falls back to that board's default swimlane
when no matching swimlane exists there yet.
Thanks to savin-msk and xet7 !
Fixes#2732,
#2905 asked for Single Logout (SLO): logging out of Wekan should also end the
identity provider's own SSO session for OIDC/OAuth2 providers that support
RP-Initiated Logout (e.g. Keycloak's
/realms/<realm>/protocol/openid-connect/logout), via the optional
OAUTH2_LOGOUT_ENDPOINT env var. This was already implemented for #6158
(getOauthLogoutUrl() in server/models/settings.js, wired into
config/accounts.js's onLogoutHook(), documented in
docs/Features/Login/Keycloak/Keycloak.md and the docker-compose.yml OAuth2
example blocks) - when unset (the default), logout is unchanged.
The URL-building logic lived inline in the Meteor method, so it had no direct
test coverage. Extracted it to server/lib/oauthLogoutUrl.js's
buildOauthLogoutUrl(), a plain-Node pure function (endpoint/serverUrl/
clientId/redirectUri in, the end_session URL out - or '' when endpoint is
unset), following the same pattern as server/lib/ldapPasswordLoginGuard.js.
getOauthLogoutUrl() now just calls it; behavior is unchanged.
Added tests/oauthLogoutUrl.test.cjs covering: the default no-op when
OAUTH2_LOGOUT_ENDPOINT is unset/empty, a Keycloak-shaped path endpoint
resolved against OAUTH2_SERVER_URL (with and without a trailing slash), an
absolute endpoint that ignores serverUrl, an endpoint that already carries a
query string, optional client_id/post_logout_redirect_uri, and percent-
encoding of the redirect URI.
Thanks to Dzordzu and xet7 !
Closes#2905,
The HTML-formatted notification email built its body from the same
plain-text line used for the non-HTML email, so the card/board URL sat as
bare text instead of a clickable link. buildHtmlNotificationLine() now
builds the HTML body directly, escaping the actor name/description exactly
as before and wrapping the URL in an escaped <a href>. The plain-text email
is unchanged.
Thanks to papimla and xet7 !
Closes#3118,
The bulk i18n fill for the new checklist-reset-interval* keys (previous
commits) had no base-language match for ace/rw/vl-SS and left them on the
English source as a placeholder; replace those three with real
translations.
Thanks to travelg and xet7 !
Lets a board member pick the new Checklists.resetInterval (none/daily/
weekly/monthly, see the previous commit) from the checklist's own action
popup, next to Move/Copy Checklist.
Thanks to travelg and xet7 !
A checkbox-type (boolean) custom field shown on a minicard rendered its
value as a bare .materialCheckBox square (and other types fell through
to plain text), which is hard to read at a glance next to the other
minicard badges. It now renders a Font Awesome fa-check-circle (true) or
fa-times-circle (false) icon instead, colored green/red, with a title
tooltip using the existing "yes"/"no" i18n keys - no new translatable
strings were needed. Every other custom field type (text, number,
currency, date, dropdown, multi-select, stringtemplate) is unchanged,
and the full card-detail checkbox editor still uses its real checkbox
input.
tests/minicardCustomFieldCheckboxIcon.test.cjs pins the icon markup for
both the labelled and full-width minicard branches, that the old
materialCheckBox/plain-text rendering is gone for checkbox specifically,
that other types are unaffected, and that the card-detail editor is
untouched.
Thanks to CarloRampini and xet7 !
Closes#3142,
server/checklistResetSchedule.js registered its SyncedCron job at module
load, but nothing loaded the module - import it from server/imports.js,
next to the other scheduled-job registrations.
Thanks to travelg and xet7 !
A checklist can now be set to automatically uncheck all of its items on a
recurring schedule via Checklists.resetInterval ('none' by default, or
'daily'/'weekly'/'monthly') and Checklists.lastResetAt. The due-date
arithmetic is a pure, unit-tested module
(models/lib/checklistResetSchedule.js), and the periodic scan
(server/checklistResetSchedule.js) reuses the existing quave:synced-cron
infrastructure server/scheduledRules.js already registers a job on, running
hourly to uncheck items of checklists whose interval has come due.
Thanks to travelg and xet7 !
Closes#3818,
Closes#4729.
Pins the source-level wiring for #3847: the Boards.stickyListHeaders field
defaults to false, its getter/setter and the member-gated Meteor method,
the listActionPopup hamburger-menu entry and its click handler, the
board-driven list-sticky-header class, and the conditional CSS rule (with a
negative check that the unconditional .list-header rule stays unsticky).
Actual on-screen scroll-pinning cannot be checked without a browser, so this
is source/CSS-level verification only.
Fixes#3847,
Two new keys for the #3626 "add an existing card as a subtask" feature:
add-existing-card-as-subtask (the action label) and
add-existing-card-as-subtask-empty (the search-popup empty state, which
reuses each locale's own existing no-cards-found translation verbatim).
Both are inserted right after add-subtask, in en.i18n.json's key order,
in all 245 other locale files, translated directly (no external
translation service) using each language's own vocabulary; a number of
low-confidence entries for smaller/under-resourced languages are best
read as an invitation for a native speaker to improve them via
Transifex, per the project's translation policy.
Thanks to ikomhoog and xet7 !
Issue #3626 asked for three things. The numeric subtask progress
indicator was already correct (pinned by the earlier #4050 work), and
multiple parents per card is a real data-model change deferred to
CHANGELOG TODO Later. This commit is the third, clearly-scoped part:
a way to pick an EXISTING card as a subtask from the current card's
Subtasks section, instead of only being able to create a brand-new one.
A new "Add existing card as subtask" trigger sits next to "Add a new
subtask" (client/components/cards/subtasks.jade). It opens a search
popup (addExistingSubtaskPopup) scoped to the current card's board,
filtered to exclude the card itself, cards already parented to it, and
anything that is already an ancestor of it (setParentId's #3328 cycle
guard would refuse those anyway, so they are filtered out before the
user can pick them). Selecting a result calls the exact existing
card.setParentId(...) method (models/cards.js) on the picked card --
the same re-parenting method every other caller uses -- so no new card
is created and no other field of the picked card is touched.
Thanks to ikomhoog and xet7 !
Pins two things from source: models/cards.js's cardCreation inserts exactly
one Activities document per Cards.insert regardless of which optional
fields the doc carries (no per-field loop, unlike the customField update
hook), and server/models/cards.js's Cards.after.insert calls only
cardCreation - so a card created with description/dueAt/assignees already
set produces exactly one watcher-notification email, not one per field.
Also pins that client/components/lists/listBody.js's addCard folds those
"More options" fields onto the SAME cardFields object passed to the single
Cards.insert call, never into a follow-up Cards.update.
Thanks to Side2005 and xet7 !
Closes#3967,
The "More options" toggle in the quick-add card composer
(client/components/lists/listBody.js/.jade, already committed) needs a
label. Translated in every locale file, reusing each language's existing
word for "options" where one is already used elsewhere in that file.
A list's cards scroll inside .list-body (overflow-y: scroll), a sibling
AFTER .list-header rather than a child of it, so the header already stays
put in the ordinary bounded-height board layout. Add Boards.stickyListHeaders
(default false) and position: sticky on .list-header when it is on, so the
header also stays pinned in any layout where .list itself turns out to be
the actual scrolling ancestor instead. The toggle is board-wide - freezing
one list's header while its neighbours scrolled normally would look
inconsistent - but it is exposed from each List's own hamburger menu
(listActionPopup) for discoverability, next to Set WIP Limit.
Thanks to JFa-Orkis and xet7 !
Closes#3847,
#4223's Bigboard view stacks every board a user belongs to on one page.
List-level dragging was deliberately scoped to stay within one board
(connectWithSelector() in swimlanes.js), but card-level dragging between
lists was never scoped that way - the cards sortable's
connectWith: '.js-minicards:not(.js-list-full)' in list.js already
connects across every board shown in Bigboard.
The drop handler still resolved the destination board from
Utils.getCurrentBoard() - the board the page happens to be routed to -
instead of from the list the card was actually dropped into. On a
normal single-board page those are the same board, so it went
unnoticed; in Bigboard, dropping a card into a list belonging to a
different board than the route's currentBoard silently moved the card
onto the wrong board.
Resolve the destination boardId from the dropped-into list's own
boardId (listData.boardId), exactly as the analogous list-to-swimlane
move in swimlanes.js already does with list.boardId, and pass it - not
currentBoard._id - to every card.move() call the stop handler makes.
Card.move() already fully supports a boardId change (label/member/
custom-field remapping, dependency cleanup), and the server-side
denyCrossBoardMove already authorizes only when the caller can write
to the destination board, so no model or permission change was needed.
Add tests/listCardCrossBoardMove.test.cjs, a source-level regression
test that pins the fix (targetBoardId/targetBoard resolution, both
card.move() calls using it) and negatively asserts card.move() is
never called with currentBoard._id directly, plus that list-level drag
scoping (connectWithSelector) stays untouched.
Thanks to lauripiispanen and xet7 !
Closes#3298,
#3294 asked for a checklist item to become a card when dragged out onto a
list, and to be marked done when dropped onto a "Done"-style list instead.
A checklist item was already draggable via its own jQuery UI sortable
(scoped to other checklists via connectWith '.js-checklist-items'), so
dropping it anywhere else - a list's own card column - always reverted with
no effect at all.
The sortable's stop handler now checks, via document.elementFromPoint at
the drop coordinates, whether the release landed over a list's
'.js-minicards' card column rather than back inside a checklist. When it
does, a new card is created titled from the item's text, in that list (and
swimlane, resolved the same way list.js's own card-drop handler resolves
it), through a pure buildCardFromChecklistItem() helper
(models/lib/checklistItemToCard.js) so the "what does the new card look
like" logic is pinned by a test without a Meteor database. The original
checklist item is left completely untouched either way - the drag always
reverts visually (sortable('cancel')), since nothing needs to move within
the checklist.
Scope decision: dropping ALWAYS creates a new card. The "mark done when
dropped on a Done-style list" half of the request is intentionally NOT
built - detecting that a list "means" Done would mean guessing from its
name or position, which is unreliable and would surprise users. That
capability is not actually missing: an item can already be marked done
directly via its own checkbox (ChecklistItems' toggleItem()), and WeKan
also already has a manual, explicit "Convert to card" action
(convertChecklistItemToCardPopup) for the same underlying card-creation
case - this drag gesture is a faster path to the same outcome, not a new
concept.
Thanks to BenjamindeJong82 and xet7 !
Closes#3294,
Rules already trigger on a MEMBER being added to or removed from a card
(joinMember/unjoinMember). assignees is a separate card field from members,
and joinAssignee/unjoinAssignee triggers mirroring the member ones (same
matchingFields shape, same Add Rule UI pattern, same workflow-palette entry)
are now wired up in server/triggersDef.js, client/components/rules/triggers/
cardTriggers.jade/.js and rulesWorkflow.js, with the new i18n keys
translated in every locale file.
tests/rulesAssigneeTrigger.test.cjs pins: the trigger registration and its
matching behavior (including that it does NOT fire on the sibling member
activity or vice versa), the Add Rule UI and workflow-palette wiring, and
that every locale file has the 4 new keys translated and in place.
Thanks to HayWo and xet7 !
Closes#3390,
#4205: a board template could be applied manually (the "Template" link on
the Create Board form opens a picker of the user's Board Templates and
copies the chosen one), but there was no way to make one the default, so
every new board meant reopening that picker each time.
Add a star toggle to each row of that picker (Template.searchElementPopup,
isBoardTemplateSearch) that marks/unmarks one "Board Templates" card as the
user's default (profile.defaultBoardTemplateId/-BoardId, both optional and
unset by default). Toggling goes through a new toggleDefaultBoardTemplate
method that only accepts a live, unarchived linked-board card from the
caller's own templates board.
The plain "type a name and click Create" board-creation flow now checks for
a default and, when set, applies it by calling the SAME copyBoard method the
manual picker already uses - not a second copy of the board-copying logic -
before falling back to the unchanged blank-board path. A user who never sets
a default sees no change at all. Deleting the underlying template board
clears it as anyone's default so creation cannot fail against a dead id.
Thanks to Jieiku and xet7 !
Closes#4205,
A third sibling of My Cards / My Due Cards: every attachment the current
user has uploaded, across every board they can see (their own boards, and
public ones), in one place. The menu entry sits right after My Due Cards
(client/components/users/userHeader.jade), and its own route (/my-attachments,
config/router.js) renders a dedicated page
(client/components/main/myAttachments.jade/.js) grouped board > swimlane >
list > card, reusing the same "open the card in place" popup mechanism
myCards.js's .js-minicard handler uses (#3640) so a click never navigates
away and loses the reader's place in a list spanning many boards.
The new `myAttachments` publication (server/publications/cards.js) filters
by BOTH the uploader (this user's own attachments only) and board visibility,
using the same boardVisibilitySelectors() the All Boards list and the board
publication already use (GHSA-gwc4-fw7p-gw58) rather than a hand-rolled
duplicate - so an attachment on a board the user cannot see is never
published, even if its userId field somehow matches. The query shape itself
lives in a small pure module, models/lib/myAttachmentsQuery.js, so it is
unit-tested without a database.
Thanks to Jieiku and xet7 !
Closes#3461,
A request for a wholly new board-visualization mode - upload a custom
background image, overlay a coordinate grid, place card markers on it -
that is a genuinely different data model and rendering approach from
WeKan's existing list/swimlane structure, not a small extension of an
existing pattern. Needs a maintainer scope decision before any
implementation is worth starting.
Typing a title starting with "[LabelName] " in the quick-add-card composer
at the bottom of a list now applies that label to the new card - creating
the label on the board first, with the same default-color pick "Add label"
uses, when no label with that name exists yet (case-insensitive match).
Only a single bracket prefix at the very start of the title is parsed; an
empty bracket, nested brackets, or a bracket with nothing left after it is
left as literal title text.
The parsing and label-resolution logic lives in the new pure module
models/lib/quickAddCardLabel.js (parseQuickAddCardLabel,
findExistingLabelIdByName, pickDefaultLabelColor), wired into addCard in
client/components/lists/listBody.js. tests/quickAddCardLabel.test.cjs covers
the parser (including the empty/nested-bracket/no-rest negative cases), the
case-insensitive label lookup, and the default-color fallback.
Thanks to mattdm and xet7 !
Closes#3986,
Board.searchCards() (used by the sidebar search and the per-list quick
search) only matched a card's title, description and custom fields via
buildCardSearchOr(). Card comments live in a separate CardComments
collection, so they were never searched at board level, even though
global search (server/publications/cards.js) already matches comment
text.
Add matchingCommentCardIds() to models/lib/cardSearch.js: given the
board's comments (as plain { cardId, text } pairs) and the search term,
it returns the de-duplicated card ids whose comment text matches,
reusing the same case-insensitive RegExp matching rule as the rest of
the search. Board.searchCards() now pulls the board's comments via
ReactiveCache.getCardComments (works the same on client Minimongo and
server Mongo) and ORs the matching card ids into the existing query.
Thanks to javiloncho and xet7 !
Closes#3841,
Pins models/cards.js Card.removeAllLabels() ($set labelIds to []),
server/rulesHelper.js wiring the removeAllLabels actionType to it, and
the Rules UI's js-add-removealllabels-action handler/button, plus the
removeAllLabels() no-label-subfield behaviour and its no-op-on-empty
semantics.
A board's own admin/member could leave the organization (or be removed)
and leave nobody - not even a global site admin - able to edit its
settings, add members to it, or archive/delete it: Boards.allow's
update/remove rule only checked board.hasAdmin(userId) against the
board's own member list. inviteUserToBoard already had a bypass for
Meteor.user().isAdmin; the whole-board update/remove rule did not.
server/lib/utils.js gets isBoardAdminOrSiteAdmin (pure, unit-tested) and
allowIsBoardAdminOrSiteAdmin (the async Meteor.users-aware wrapper), and
server/permissions/boards.js's update/remove rules now use it instead of
the board-only allowIsBoardAdmin. Scoped to the whole-board rule only -
the narrower rules/actions/triggers/comments allow rules keep the
board-only check, pinned by a negative test.
Thanks to relikd and xet7 !
template tokens to the Rules "send an email" action.
The "send an email" rule action sent a bare message with no reference to
the card that triggered it - no title, no link, and no way to pull in the
list, board or triggering member. performAction() already builds a
ruleVars map and substituteVars() already replaces {name} tokens in email
subject/body (added for #2475), so this extends that existing mechanism
rather than building a new one:
- {cardLink} resolves via Card.absoluteUrl() (models/lib/cardUrl.js), the
same helper card activity notification emails already use, so no new
URL-building code is needed.
- {member} resolves the activity's memberId (the member added/removed/
etc.) falling back to the acting user when the activity records none.
- {card}/{list}/{board} are short aliases of the existing cardname/
listname/boardname/username variables, documented next to the email
fields via a new r-email-vars-hint hint text so the tokens are
discoverable without external docs.
- Independently of any template the user configures, the card's title and
link are now always appended to the sent email body, so #3301's core ask
(a direct link to the card) holds even for a rule someone set up before
this change with no tokens at all.
substituteVars() moves out of server/rulesHelper.js into a new pure
models/lib/ruleVarsSubstitute.js so it can be unit tested directly, the
way models/lib/cardUrl.js next to it already is; tests/ruleEmailVars.test.cjs
covers token substitution (including case-insensitivity, unknown tokens
left as literal text, and malformed braces not being mistaken for tokens),
the automatic card-link footer, and that the new hint text is present and
translated.
Thanks to vossilius and ivan-paleo and xet7 !
Closes#3304,
Closes#3301,
declared MIME type, and reject a dangerous mismatch (e.g. an executable
or script renamed with an image/document extension).
Restores the code from an earlier local commit (61e857d96) that a later
concurrent "Update changelog." commit (715140a2bb) accidentally reverted
by committing a stale working tree - CHANGELOG.md's entry for this
already points at 61e857d96, which still contains the original change
in its tree; this recreates it in the current tree so HEAD is not
missing the guard it documents.
fileValidation.js already sniffed content for dangerous HTML/SVG/XML
markup, but a spoofed executable (a Windows PE .exe, an ELF binary, a
Mach-O binary, or a shell/batch script) disguised with an image or
document extension and Content-Type passed through untouched, since
those binary formats were never on the dangerous-MIME deny-list.
models/lib/uploadContentMismatch.js is a pure decision module (no
server, no I/O) that flags only a MEANINGFUL, dangerous mismatch:
content that magic-byte-sniffs as executable/script while the client
declared an image/document/text/audio/video/archive type. It
deliberately does not flag compatible textual differences (text/plain
vs text/csv) to avoid false-positive breakage of legitimate uploads,
and does not flag an executable honestly declared as one (the
allow-list already governs whether executables are allowed at all).
fileValidation.js's isFileValid() - the single choke point already used
by both models/attachments.server.js and models/avatars.server.js - now
sniffs the file's real type with the `file-type` package (already a
dependency, MIT-licensed, used the same way for extension correction in
models/lib/fileTypeCorrection.js) and rejects a dangerous mismatch,
logging the blocked attempt to Admin Panel -> Problems under the
existing 'file.mime' security-log key (CWE-434, MimeBleed). Logging is
wrapped so a detection failure can never block a legitimate upload or
break the guard.
tests/uploadContentMismatch.test.cjs unit-tests the pure decision
function directly: positive cases for legitimate uploads of each
declared type, negative cases for a PE/.exe, an ELF binary, a Mach-O
binary and a shell/batch script each disguised with an image or
document type, and a search across models/ and server/ proving no
other module re-implements its own bypassing magic-byte check and that
both upload paths (attachments, avatars) go through the same guard.
Thanks to blaggacao and xet7 !
Closes#3274,
models/lib/checklistTemplateCopy.js pulls the "copy a checklist/item
document onto another card" logic out of Checklists.copy() /
copyAllFromCardToCard() (#4017) into plain, Meteor-free functions -
the same split already used for subtask copying
(models/lib/subtaskCopy.js) and bulk checklist-item text editing
(models/lib/checklistItemsAsText.js) - so the copy semantics are unit
tested directly: the copy reproduces the source's checklist/item
content, drops the source _id (a fresh one is assigned on insert),
re-homes onto the destination card/board, places an appended checklist
after the target's own (existing checklists are read but never
mutated), and forces a copied item unchecked when resetChecked is set
while leaving the default (ordinary "Copy Checklist" / card copy)
behaviour unchanged. Checklists.copy() and copyAllFromCardToCard() now
call these builders instead of repeating the field-by-field copy
inline; behaviour is unchanged (the full node suite's existing
checklist tests still pass).
Thanks to Th0mas89 and xet7 !
Completes the per-board default / per-user override for minicard label
text: models/lib/labelTextVisibility.js is the pure resolution function
(user override > board setting > historical default) that
client/lib/minicardLabelText.js now calls instead of duplicating the same
three-way decision, and tests/labelTextVisibility.test.cjs pins all three
cases plus the migration-safety case (an existing board/user with nothing
stored still shows label text). server/models/boards.js's REST
cardSettings whitelist also gets showLabelText, matching every other
board-level card setting there.
A Worker's checkbox was gated behind the same canModifyCard/write check that
also gates editing and deleting a checklist item, so it never drew a
clickable box at all - the server's allow rule refused the write too. Give
checking/unchecking its own, narrower capability (like the existing
move/self-assign carve-out for cards, models/lib/workerCardWrite.js): a
Worker may $set isFinished and nothing else on a checklist item
(models/lib/workerChecklistItemToggle.js), enforced field by field in
server/permissions/checklistItems.js. The client mirrors it with
Utils.canCheckChecklistItem / the canCheckChecklistItem Blaze helper, so
client/components/cards/checklists.jade now draws the checkbox under that
helper while everything else on the row (title edit, drag handle, due-date
edit, delete) still requires the full write capability.
Thanks to mweiss237 and xet7 !
Fixes#3307,
Fields, Labels, Dates and Members sections.
The opened card always rendered its sections in one fixed order, with no
way to move Description earlier or have Custom Fields follow it. Boards
now store a cardFieldOrder array; models/lib/cardFieldOrder.js resolves it
against the historical default order, dropping unknown keys and filling in
any missing section so a stale or partial value can never hide or
duplicate a section. cardDetails.jade renders these five sections from
that resolved order instead of a hardcoded sequence, each now its own
template (cardFieldSectionLabels, ...Dates, ...Members,
...CustomFields, ...Description) included from an each loop; Dependencies
+Sort stay a fixed appendage right after Members and Vote+Poker stay one
right after Custom Fields, so a board that never touches the setting
renders exactly what it always did. Checklists, Attachments and Activity
are left out of this pass - they sit in their own flex/right-column
layout further down the template, and moving them was not needed for the
issue's ask (move Description earlier, custom fields after it) and would
add layout risk this environment cannot verify visually.
Board Settings / Card Settings gets a new "Card field order" list with
up/down buttons per row. Up/down rather than a drag library: this
codebase's existing jQuery-ui-sortable usages (list/swimlane/board
reordering) are heavier drag-and-drop over board layout, not a simple
settings list, so buttons are the simpler, safer mechanism here.
Thanks to mimZD and xet7 !
Closes#4448,
WeKan's IFTTT-style Rules already had per-label "add label X" / "remove
label X" card actions (models/cards.js addLabel/removeLabel, wired in
server/rulesHelper.js and the label dropdown in
client/components/rules/actions/cardActions.jade/.js). Removing every
label from a card required one "remove label" action per label.
Card.removeAllLabels() sets labelIds to an empty array in one update
(a card with no labels is a no-op), and a new "Remove all labels" rule
action (actionType 'removeAllLabels', no label-selection sub-field)
calls it from a new dropdown entry next to the existing label actions,
mirroring the existing "Remove all members" action's wiring.
Thanks to basketball00011 and xet7 !
Closes#3432,
WeKan's IFTTT-style Rules already had per-label "add label X" / "remove
label X" card actions (models/cards.js addLabel/removeLabel, wired in
server/rulesHelper.js and the label dropdown in
client/components/rules/actions/cardActions.jade/.js). Removing every
label from a card required one "remove label" action per label.
Card.removeAllLabels() sets labelIds to an empty array in one update
(a card with no labels is a no-op), and a new "Remove all labels" rule
action (actionType 'removeAllLabels', no label-selection sub-field)
calls it from a new dropdown entry next to the existing label actions,
mirroring the existing "Remove all members" action's wiring.
Thanks to Southclaws and xet7 !
Closes#3432,
Issue #3310 (2020) asked for three things. Reading the current code shows all
three are already implemented, some in a stronger form than requested:
1. Invite code management from the Admin Panel: superseded by "Invite via
Email" in Admin Panel -> Settings (settingBody.js), which calls the
sendInvitation server method to generate and email a per-invitee code
(icode), validated at sign-up (server/models/users.js) - an admin-driven
per-person code rather than the single static field the report found.
2. Admin ability to delete a user account: Admin Panel -> People already has
this. Each row's "more settings" link opens the settingsUser popup
(Popup.open("settingsUser") -> template settingsUserPopup), whose
#deleteButton calls the removeUser server method.
3. Anonymous viewing of public boards: a board's own URL (/b/:id,
/b/:id/:slug) carries no sign-in trigger in the router, and the board
publication's visibility selector already includes { permission: 'public' }
for a subscriber with no userId at all (models/lib/boardVisibilitySelectors.js).
No behaviour changed; tests/issue3310FeatureRequests.test.cjs pins all three.
Thanks to Cupara and xet7 !
Fixes#3310,
Both issues ask the same question: which users are actively using WeKan,
and for how long. The `lastConnectionDate` field already existed on the
user schema but was only ever written from a commented-out, env-gated
block in server/publications/users.js - so WeKan never actually recorded
it. Accounts.onLogin now stamps it on every successful login
(server/lastActiveOnLogin.js), and an open client session refreshes it
every two minutes via a `usersHeartbeat` method
(client/lastActiveHeartbeat.js, server/methods/lastActiveHeartbeat.js) -
a periodic timestamp, not a WebSocket/real-time presence system, which is
more than either issue asked for.
Admin Panel / People gets a "Last active" column showing each user's
timestamp with an online-now badge when it is within five minutes
(models/lib/lastActive.js holds the pure recency check, reused by the
unit test). "Last active" and "Online now" are added to en.i18n.json and
translated into 203 other locale files; the remaining minority keep the
English source as the untranslated-everywhere placeholder.
Thanks to eccaw and xet7 !
Closes#3678,
Closes#3734,
A card URL pasted into Discourse, Slack, Discord etc. now renders an inline
preview: a connect middleware sets request.dynamicHead (the same injection
point Meteor's WebApp boilerplate generator already supports, following the
precedent in server/routes/customHeadAssets.js) with og:title,
og:description, og:url and og:image tags for the '/b/:boardId/:slug/:cardId'
route, before Meteor's normal SPA shell is served. The tags are only ever
built when the card's board is public (board.isPublic()) - a private board's
card serves the normal, unmodified page, since an unfurl request carries no
auth. The gating and rendering logic lives in server/lib/cardOgTags.js as a
Meteor-free pure module with unit + negative test coverage.
Thanks to yelloff and xet7 !
Closes#3456,
Checklists.copy() now takes an options.resetChecked flag so a copied
item can be forced unchecked regardless of its source isFinished state,
and a new Checklists.copyAllFromCardToCard(sourceCardId, targetCardId)
appends every checklist of a source (e.g. template) card onto a
destination card's existing checklists, in source order, without
touching what is already there. Both are used by the new "Copy
Checklist From Template" card action (client/components/cards/checklists.js
and .jade), which reuses the same board/swimlane/list/card picker as
Move/Copy Checklist.
Thanks to Th0mas89 and xet7 !
Closes#4017,
The existing "Dropdown" custom field type only ever stored one selected
option. Add "dropdownMultiSelect" (models/customFields.js), reusing the
exact same settings.dropdownItems option-list definition mechanism and its
Board Settings editing UI (client/components/sidebar/sidebarCustomFields.js/
.jade) - only the value stored on a card differs: an array of selected item
ids instead of a single one.
On a card, the new type renders as a checkbox list (reusing the app's
existing toggle-checkbox interaction rather than a <select multiple>), and
its value round-trips through Cards.setCustomField() the same way
stringtemplate's own array value already does
(client/components/cards/cardCustomFields.js/.jade).
models/lib/customFieldsWD.js's resolveTrueValue() now resolves a
dropdownMultiSelect's array of ids to the matching item NAMES, joined for
display, so every place that already read a dropdown's trueValue (the
minicard badge, the CSV/PDF/Excel exporters) shows the new type correctly
without further changes there. The CSV/PDF/Excel exporters and csvCreator's
CSV header/definition parsing are updated to resolve
dropdownMultiSelect's array-of-ids the same way the single-select dropdown
already resolves its single id.
Thanks to huma2000 and xet7 !
Closes#4166,
My Cards spans many boards, so its card links were a plain
`a.minicard-wrapper(href=card.originRelativeUrl)` with no click handler.
Clicking one followed the href and navigated the whole browser to that
card's own board, losing the user's place in the cross-board My Cards list.
Fix it by reusing the mechanism the app already uses for opening a card
from other cross-board contexts - global search results
(client/components/cards/resultCard.js) and the Board Table view's Edit
link (client/components/boards/tableView.js): intercept the click,
subscribe `popupCardData` for that card, set the `popupCardId` /
`popupCardBoardId` Session variables, and open the shared `cardDetails`
popup in place. The `href` stays on the link so middle-click/ctrl-click
and a no-JS fallback keep working.
Thanks to javen9881 and xet7 !
Fixes#3640,
A checklist could previously only be edited one item at a time through its
per-item HTML row - reordering, copying between checklists/cards, or a bulk
rewording meant a click-drag or a click-edit-save per item. WeKan already
had "one line = one new item" for ADDING items (the newline-becomes-item
toggle), but nothing let a user rewrite the items an existing checklist
already has as one text block.
Adds "Edit as text" to a checklist's actions menu (alongside Export/Import,
Delete, Move, Copy). It opens a textarea pre-filled with the checklist's
current items, one per line, using the Markdown-checklist convention
`[x] Done item` / `[ ] Todo item` for checked state (a plain line with no
marker defaults to unchecked, so text pasted from elsewhere still works).
Saving replaces the item list with what was typed, in that order.
The parsing and the replace-plan are pure functions
(models/lib/checklistItemsAsText.js): checklistItemsToText/
parseChecklistItemsText convert between the textarea's text and
{title, isFinished} objects, and planChecklistItemsTextUpdate matches each
parsed line against the checklist's current items by unchanged title text
(consumed top-to-bottom, so reordered duplicates still pair 1:1) - a match
KEEPS that item's existing document (only sort/isFinished change), so any
other metadata on it, notably the #4755 due date, survives an edit that
doesn't touch its text. Only a line whose title has no remaining match
becomes a new item, and only an existing item whose text is gone from the
new text is removed.
Thanks to gerroon and xet7 !
Closes#4218,
client/features/boards.js explicitly imports every board view's jade/js/
css (Meteor does not auto-load client files here) - bigboardView.jade/
.js/.css were missing from that list, so the new view could not have
rendered. Add them next to the other board views.
Extend tests/boardViewMenu.test.cjs's VIEWS table with the new entry so
every existing wiring check (menu order, icon, click handler, isView*
helper + boardBody.jade branch, the anonymous-user whitelist, the
en.i18n.json label, profile.boardView's allowedValues, the tooltip name
map, and the "templates are registered" check) covers Bigboard the same
as the other 19 views.
"Bigboard" is a proper noun (Kanboard's plugin of the same name), like
"Gantt"/"Frappe Gantt" already are - add it to fill-translations.mjs's
isInvariantSource() allowlist so it is not flagged as an untranslated
string in any locale.
Thanks to Jieiku and xet7 !
Board Settings / Card gets a new "Comments on minicard" row, following the
same allowsX/allowsXOnMinicard pattern as every other Card Settings toggle
(e.g. Received date). It is opt-in and OFF by default
(allowsCommentsOnMinicard), so existing boards are unaffected.
When enabled, the minicard shows up to 3 of the card's most recent
comments, each truncated to 140 characters, reusing the same comments()
card helper the existing comment-count badge already calls - no new
subscription. A "more" affordance appears when there are more comments
than shown or a comment got truncated; it relies on the minicard already
being a link to the full card (client/components/lists/listBody.jade's
a.minicard-wrapper.js-minicard) rather than adding an in-place expand
interaction - display only, no reply/edit from the minicard.
Thanks to Meeques and xet7 !
Closes#4285,
Cards.helpers().link(boardId, swimlaneId, listId) already created a
linked-card mirror on a different board, and cardDestinationPicker already
gave Move/Copy card a board/swimlane/list chooser, but nothing let a user
create a link from the card's own hamburger menu to an EXISTING board -
only the list's "search/insert as link" composer could do that, and only
into the current board. A new linkCardToBoardPopup, wired next to Move
card/Copy card, reuses both: it opens the same picker and calls the
existing card.link() on Done, never mutating the original card.
Thanks to HT-Marley and xet7 !
Closes#4281,
Custom fields rendered alphabetically by name everywhere - the board
settings sidebar list and every card - with no way to change it, so users
worked around it by prefixing names with numbers (#4165).
Add a numeric `sort` field to the CustomFields schema (optional, so fields
created before this exist keep sorting by name as a fallback). The board
settings sidebar list (client/components/sidebar/sidebarCustomFields.jade/js)
gets a drag handle and jQuery-ui sortable, mirroring the card-labels popup's
own reordering (client/components/cards/labels.js) - the smallest existing
pattern for a short settings list that rewrites its whole order on drop.
Dropping recomputes sequential `sort` values with computeSortIndexMapping(),
the same pure helper the All Boards page already uses for its own
drag-reorder (models/lib/boardSortReorder.js), so no new reordering logic
was added. A newly created field defaults to the end of the board's current
list (the count of existing fields), not the top.
models/lib/customFieldsWD.js - the shared matcher that builds a card's
custom-field list from its board's definitions - now sorts by `sort`
ascending instead of by name, falling back to name for fields with no
`sort` yet. This is the one place both the card detail view and the
card's custom-fields popup get their order from, so no other rendering
path needed changes.
Thanks to huma2000 and xet7 !
Closes#4165,
Add docs/Features/Login/Authelia.md with Snap and Docker settings mapped
to Authelia's OIDC endpoints (authorization_endpoint, token_endpoint,
userinfo_endpoint under /api/oidc/*, from Authelia's own OIDC docs),
matching the format already used for Keycloak and Zitadel, and note that
Authelia does not yet implement RP-Initiated Logout so OAUTH2_LOGOUT_ENDPOINT
should stay unset for it. Also linked from docs/README.md's Login Auth list,
the OAuth2 providers list in docs/Features/Login/OAuth2.md, and given the
same commented OAUTH2_* example block in docker-compose.yml and every other
docker-compose-*.yml variant that carries the OAuth2 examples.
Thanks to tamaskan and xet7 !
Closes#4210,
The reporter saw the minicard subtask badge stay at "0/n" after giving a
subtask an End Date, and expected that to count as "done". Reading
models/cards.js shows the counter is not broken: subtasksFinishedCount()
counts subtasks with archived: true (the numerator), allSubtasksCount()
counts every subtask regardless of archived state (the denominator), and
Card.archive() - the actual "finish a subtask" action - sets that flag and
recurses into children. setEnd(endAt) only ever writes { endAt }; it never
touches archived, by design, since an end date is a due-date field, not a
completion flag. Archiving a subtask does correctly increment the badge.
Added a regression test that pins this: the numerator/denominator source,
that archiving M of N subtasks yields M/N, and a negative case that setting
only an end date leaves the count at 0/n.
Thanks to ufalke and xet7 !
Fixes#4050,
Add "Bigboard" to the Board View menu, right after Dashboard, matching
the existing 19-entry pattern (menu row in boardHeader.jade, click
handler + boardViewName() entry in boardHeader.js, isViewBigboard()
helper + boardBody.jade branch, the two whitelist arrays in
client/lib/utils.js, and profile.boardView's allowedValues in
models/users.js).
Unlike the other views, Bigboard renders every board the current user
is a member of, not just the open one - the same idea as Kanboard's
BigBoard plugin. The new bigboardView template (bigboardView.jade/js)
queries the user's boards with the same membership selector the All
Boards page uses, subscribes each one's lists/swimlanes/cards through
the existing 'board' composite publication, and stacks each board as
its own section reusing the existing listsGroup/list/card templates -
so editing, dragging and opening a card behave exactly as on a normal
board page.
Rendering several boards' lists on one page at once exposed a bug the
single-board case never could: list drag-and-drop connects via a plain
'.js-swimlane, .js-lists' jQuery UI sortable selector, which would let
a list be dragged out of one board's section into another's now that
more than one board's lists share a page. Added a data-board-id
attribute to the swimlane/listsGroup root elements and a
connectWithSelector() helper (swimlanes.js) that scopes the connect
selector to the dragged list's own board id when one is present -
ordinary single-board views still have exactly one board id on the
page, so their behaviour is unchanged.
Thanks to Jieiku and xet7 !
Previously, linking a card to a board required first creating the board
separately and then using the existing "Link to board" action to find it.
Add a new, adjacent action to the card's hamburger menu, "Create board from
this card", that prompts for the new board's title (defaulting to the
card's own title), creates the board the same way normal board creation
does, and links the current card to it - setting the exact same
type/linkedId fields the existing "link to a whole board" flow sets - all
without leaving the card.
The new server method, createBoardFromCard, refuses to convert a card that
is already a link or a template, and requires write access on the card's
own board before creating anything.
Thanks to Xilef11 and xet7 !
Closes#4495,
Admin Panel -> Settings -> Visibility gets a new checkbox beside "Public
boards": "Only admins can create boards"
(tableVisibilityMode-boardCreationAdminOnly, off by default). It follows
the exact TableVisibilityModeSettings pattern its sibling
tableVisibilityMode-allowPrivateOnly already uses: a collection doc seeded
in server/models/collectionBootstrap.js, a jade checkbox and reactive
helper in settingBody.jade/js, and a write in the section's own Save
handler.
The real enforcement is server-side: createBoardWithInitialSwimlanes
(server/models/boards.js) now rejects the call with a not-authorized error
when the setting is on and the caller is not isAdmin === true, before the
board is ever inserted. The client mirrors this only as a convenience - a
new client/lib/boardCreationAllowed.js helper hides the top-bar "+" (header
header.js/.jade) and the All Boards "Add board" tile (boardsList.js) for a
restricted non-admin, but nothing depends on that for security.
A full per-user allow/deny override was left out of this pass: it would
need is own schema field, a People/Admin Panel UI to flip it per account,
and server enforcement layered under the global toggle, which is a larger
change than this issue's "let an admin forbid board creation instance-wide"
core request. The global toggle covers that request cleanly on its own.
Added imports/i18n/data/en.i18n.json's board-creation-admin-only string and
a direct translation (no external translation API) in all other locale
files, in en.i18n.json's key order. tests/boardCreationAdminOnly.test.cjs
pins the default-off setting, the checkbox/handler wiring, the server-side
admin check (and that it runs before the insert), the shared client helper,
the i18n key placement, and - as a negative test - that no OTHER
Boards.insertAsync call site was silently added outside the two already
known and deliberately ungated ones (the per-user Templates container and
createBoardFromCard).
Thanks to belf88 and xet7 !
Closes#4475,
Board cloning gained an opt-in "Without cards" checkbox (see commit
d4876eca3, which carries this fix's code alongside an unrelated
changelog entry due to this checkout being shared with other
concurrent work) that threads a withoutCards flag from the Clone
Board popup through copyBoard, Boards.helpers().copy() and
Swimlanes.helpers().copy() down to the single place cards are
actually copied. This pins: the i18n key exists in English and every
locale, the flag defaults to false so unchecked cloning is unchanged,
the per-list card-copy loop is the one gated call site (a negative
check that no second, unguarded card.copy() sneaks cards back in),
and the client popup/checkbox wiring passes withoutCards through to
the Meteor call.
Thanks to e-gaulue and xet7 !
Closes#4726,
Group cards by assignee, clustered under each assignee's name as a
heading, for a read-only overview well suited to a team stand-up. A
card with several assignees appears under each; a card with none falls
into "No assignee". Reuses the same grouping/translation fold the
Dashboard and Time views already use (models/lib/chartCalculations.js's
NO_ASSIGNEE_GROUP/translateGroupLabel), now generalized into
computeCardsByAssigneeGroup, which returns the grouped cards themselves
rather than a count/hours total. Wired end to end like every other
board view: a "Group by Assignee" Board View menu entry, an
isViewGroupByAssignee() helper/boardBody.jade branch, the
client/lib/utils.js whitelist, the profile.boardView schema, and a
tooltip-name-map entry. Each card row is a simple title + due date +
overtime marker, deliberately not a minicard re-render, and clicking a
card navigates to it like any other view - no drag-and-drop, no export.
Thanks to xet7 !
Closes#4688,
An admin with several teams (19 users, 6 teams in the report) could not narrow
the People list to one team's members - only the existing Show filter
(All/Locked/Active/Inactive/Admin) and the free-text search box. A user's team
membership already lives in their own `teams` array (models/users.js,
`teams.$.teamId`), so the People pane's controls row gets a second dropdown,
Team, built from every team and matched against that field the same way Show
already narrows the query. Both dropdowns share `.js-table-page-filter`; a
`data-filter` attribute (already emitted by the shared table page for each
filter) tells the change handler which ReactiveVar to update.
Thanks to hesco and xet7 !
Closes#4510,
?assignee=johndoe, ?member=janedoe and ?label=urgent now pre-filter a board
on load, reusing the existing Filter sidebar object/API rather than a new
filtering engine - useful for embedding a pre-filtered board view in another
tool (e.g. an iframe). Query params are parsed once, when the board
subscription becomes ready (client/components/boards/boardBody.js), and
resolved to member/assignee ids by username and to label ids by name via
client/lib/filterQueryParams.js, a pure module covered by
tests/filterQueryParams4540.test.cjs. This only reads params on load; it does
not sync the URL back as filters change.
Thanks to thrademaker and xet7 !
Closes#4540,
Clicking a comment's or an activity's timestamp now links to a
shareable permalink - the card's own URL plus a #comment-<id> or
#activity-<id> fragment. Visiting that link loads the card and then
scrolls to and briefly highlights the matching comment or activity,
reusing the existing swimlane/list reveal-on-load mechanism
(models/lib/revealBoardItem.js, client/lib/revealBoardItem.js),
extended here to read the two new kinds from the URL hash instead of
a route param. A small icon next to the timestamp copies the same
URL to the clipboard, reusing the existing copyTextToClipboard/
showCopied pattern already used for card/list/swimlane links.
Thanks to xet7 !
Closes#4757,
Checklist items only ever inherited the card's own due date; there was no way
to give one item its own deadline. ChecklistItems now has an optional dueAt
field, plus getDue/setDue/unsetDue helpers that mirror Cards' own due-date
methods exactly. Each item row shows a small clock-icon trigger (or, once a
due date is set, a compact badge) that opens a date/time picker - reusing the
same dateBadgeBody/editDateForm markup and datePickerEvents the card's own
due-date popup already uses, so nothing new was added to the date-picker
stack. An item whose due date has passed turns red via the same dueDateClass
decision the card's own badges use. No new translation key was needed:
the popup title and badge tooltip reuse the existing card-due/card-due-on/
editCardDueDatePopup-title strings.
tests/checklistItemDueDate.test.cjs pins the schema field shape, the
getDue/setDue/unsetDue methods, that the badge/popup templates exist and
reuse the shared markup rather than a new date-picker, that the popup does
not reuse the card-specific setupDatePicker helper (which would resolve the
wrong document from inside an open card dialog), that overdue styling goes
through the shared dueDateClass function, and that no member-assignment was
added alongside it.
Thanks to DimDz and xet7 !
Closes#4755,
The classic Pomodoro Technique - a fixed 25-minute work interval, then a
break (5 minutes, or a longer 15-minute break every 4th completed work
interval) - as its own, separate block from the unrelated Flowtime feature
(#3919, open-ended sessions with no fixed interval): its own template,
button group and field names, sitting alongside cardFlowtime's block in
cardDetails.jade rather than replacing or restructuring it.
client/components/cards/cardPomodoro.{js,jade,css} is the new card-detail
UI: a configurable work-length input and Start Pomodoro button, a live
countdown (the same Meteor.setInterval idiom cardFlowtime.js already uses)
with a Work/Break phase label and completed-interval count, and a Stop
button. Registered in client/features/cards.js the way every other
client/components/cards/*.jade/js/css file is.
Card.completePomodoroWorkInterval() - called client-side when a work
countdown reaches zero - adds the interval's duration, in hours, into the
card's EXISTING spentTime field via the same setSpentTime() helper the
manual time-entry popup and Flowtime both already use, increments
pomodoroCount, and switches to a break interval; completing a BREAK
interval adds no time and returns to ready-to-start rather than
auto-starting the next work interval. Stop/Reset (stopPomodoro()) credits
whatever elapsed so far if stopped mid-work-interval (consistent with
Flowtime's own stopFlowSession()), adds nothing if stopped mid-break, and
clears every Pomodoro field back to its empty/null default.
Five new i18n keys (pomodoro, pomodoro-start, pomodoro-work,
pomodoro-break, pomodoro-completed) added to en.i18n.json and given a
real, direct translation - not an English placeholder - in every other
locale file, in the same key position, with the %s placeholder preserved;
the "stop" button reuses the existing generic "stop" key rather than
adding a near-duplicate.
tests/pomodoroTimer.test.cjs pins: the schema fields and methods exist and
are additive next to Flowtime's (no rename/reuse of its fields); a
completed work interval adds its duration via the existing setSpentTime()
helper and switches to break; a completed break interval adds no time and
does not auto-start the next work interval; the every-4th-interval long
break rule; the UI is wired and registered as its own block; and all
locale files carry the new keys, in order, with real translations and the
%s placeholder intact.
Thanks to xet7 !
Closes#4862,
A short, synthesized Web Audio tone (OscillatorNode + GainNode envelope)
plays when a checklist item transitions from unchecked to checked, gated on
a new per-user Member Settings preference ('profile.checklistDingSound'),
off by default. The sound is synthesized rather than a bundled audio file,
since a previously proposed bundled sound was not copyfree/MIT/BSD-licensed
and was rejected for that reason.
Thanks to C0rn3j and xet7 !
Closes#5427,
Unlike Pomodoro's fixed 25-minute work/break cycle, Flowtime has no fixed
interval: you start a work session and keep going as long as you are in
flow, tally interruptions as they happen without stopping the clock, and
stop the session when the flow naturally ends.
This integrates with WeKan's existing time-tracking feature
(client/components/cards/cardTime.js/.jade, models/cards.js
setSpentTime()/setIsOvertime()) rather than being a disconnected feature,
per the issue's own "related to Timetracking #812":
- models/cards.js gains three schema fields for the in-progress session -
flowStartAt (Date), flowInterruptions (Number), flowUserId (String) -
and startFlowSession()/addFlowInterruption()/stopFlowSession() helpers
that mirror the shape of the existing setSpentTime()/setIsOvertime()
helpers. Persisting server-side (not Session/localStorage) means a page
reload does not lose an in-progress session.
- stopFlowSession() computes the session's duration and ADDS it, in hours,
into the card's EXISTING spentTime field via the same setSpentTime()
the manual time-entry popup already uses, then clears the session
fields - Flowtime feeds the same total, it does not keep a separate one.
- addFlowInterruption() only increments the tally; it does not touch
flowStartAt, so the clock keeps running through an interruption.
- client/components/cards/cardFlowtime.{js,jade,css} is the new card-detail
UI: a Start Flow button, a live elapsed-time readout (Meteor.setInterval,
the same idiom client/components/settings/problemsSummary.js already
uses) with the running interruption count, an Add Interruption button,
and Stop Flow. Only Utils.canModifyCard() may use the controls. Wired
into client/components/cards/cardDetails.jade next to the existing
cardSpentTime badge, and registered in client/features/cards.js the way
every other client/components/cards/*.jade/js/css file is (Meteor does
not auto-load them).
- Five new i18n keys (flowtime, flow-start, flow-stop,
flow-add-interruption, flow-interruptions) added to en.i18n.json and
given a real, direct translation - not an English placeholder - in
every other locale file, in the same key position, with the %s
placeholder preserved.
tests/flowtimeSession.test.cjs pins: the schema fields and helpers exist;
the manual time-entry popup is untouched; only start/interrupt/stop write
the flow fields, each scoped to this.getRealId() (no cross-card leakage);
stopFlowSession's arithmetic adds into, rather than replaces, spentTime;
the UI is wired and registered; and all locale files carry the new keys,
in order, with real (non-English) translations and the %s placeholder
intact.
Thanks to xet7 !
Closes#3919,
#812's 39-comment thread repeatedly asked for external timesheet
integrations (Kimai, Harvest, Titra) that were never resourced - the
maintainer's own 2021 comment quotes a ~1000 EUR / 4-month estimate for a
Kimai sync, shelved shortly after. What the thread DID converge on that
fits inside WeKan itself: "reporting total hours by resource and task
type" (the issue's own words), and export - both added here without any
external service.
server/lib/boardChartData.js answers a new 'time' chartKey with
computeTimeByGroup (models/lib/chartCalculations.js: sums each card's
spentTime per assignee, not a card count - the same shape as
computeDashboardGroups but summing a value instead of counting cards) and
computeTimeByCard (one row per card with logged time, largest first),
scoped to non-archived cards like the Time view's existing summary. 'time'
is registered as a real chartKey in models/exportCharts.js and
models/lib/chartExportRows.js, so it reuses the exact same
/api/boards/:boardId/charts/:chartKey/export* PDF/Excel routes and
ExporterChartPDF/ExporterChartExcel every other board report chart already
uses - one export pipeline, not a second one just for Time. The Time board
view calls the same boardChartData method (chartKey 'time') the 10 report
charts already use and shows the same two breakdowns alongside its
existing 3-row summary, kept exactly as it was.
Thanks to xet7 !
Closes#812,
#5758 needs a Windows host, node-gyp/MSVC build tools, an Active Directory
domain, and a real SSPI handshake to build or verify at all - it also sits
directly in the authentication path, where a wrong implementation done
without that environment is a security risk rather than a convenience.
#5707 already has a real fix (Admin Panel's "Invite People" form now shows
success/failure feedback) and is no longer open work.
A list with no swimlaneId of its own (shared/pre-migration) renders once
per swimlane in Swimlanes view - the same list document, one row per
swimlane (client/components/swimlanes/swimlanes.js's `lists()` helper
already documents this: "shared / pre-migration lists (swimlaneId empty or
null)" are returned for every swimlane). Collapsing/expanding it was a
single Session/profile key keyed only by list._id, so collapsing the list
in swimlane 1's row also collapsed swimlane 2's row of the very same list.
Utils.getListCollapseState/setListCollapseState (client/lib/utils.js) now
take an optional swimlaneId and fold it into the storage key
(`${list._id}:${swimlaneId}`) used for both the Session cache and the
persisted state (the setListCollapsedState Meteor method / the anonymous
public-board cookie fallback) - a bare list._id key, used outside Swimlanes
view or when swimlaneId is absent, is unchanged, so existing stored state
still applies exactly as before. Every read/write site resolves it via the
same containerSwimlaneId pattern #6660 already established for scoping a
board-wide list's CARDS per swimlane (client/components/lists/
listHeader.js, listBody.js): walking up parent Blaze data contexts to find
the enclosing swimlane, now extracted into a shared resolveContainerSwimlaneId
function and reused by list.js's own collapsed() helper and the resize-
handle visibility logic (the latter via a View-walking variant, since it
runs from async/onCreated code with no active Blaze render for
Template.parentData() to read from).
Archive is unaffected by this: Lists.archive()/restore() already scope to
`this._id`, and a board-wide list archived from one swimlane correctly
disappears from every swimlane's row of it - because it IS the one shared
list document, not a different one.
Thanks to xet7 !
The request asked for an act-editCard action on the global webhook so card
edits could be tracked. That already happens: server/models/cards.js logs an
Activities entry for title (a-changedTitle, #3619), description
(a-changedDescription, #5482) and due/start/end/received date changes, and
server/models/activities.js's Activities.after.insert hook turns each into
act-${activityType} and dispatches it to any enabled integration on the
card's board OR the global webhook id, filtered by
activities: { $in: [description, 'all'] }. Added a source-pattern regression
test pinning this path so it cannot silently regress.
Thanks to Rishats and xet7 !
Fixes#4912,
The Admin Panel -> Accounts -> "Invite People" form called the
sendInvitation Meteor method with a callback that took no parameters at
all, ignoring both the error and the result (a commented-out "TODO -
show more info to user" sat next to it). So an admin using that form
got no feedback whatsoever when a mail-send failure happened (e.g. the
server's mail transport is not configured, which is what
sendInvitationEmail's Meteor.Error('email-fail', ...) reports) -- the
Send button just stopped spinning either way.
The member "Invite People" popup (userHeader.js) already surfaces this
via a red/green #invite-people-infos message, so settingBody.js now
does the same: read the callback's error argument and write the same
success/error message into a matching #invite-people-infos element,
added to settingBody.jade.
Thanks to Rayene123 and xet7 !
Fixes#5707,
The Dashboard view's By Assignee/By Label bars grouped a card with no
assignee or label under the literal English word "none" - untranslated in
every language, on the live chart, the data table, and the PDF/Excel
export alike (models/lib/chartCalculations.js's computeDashboardGroups
hardcoded {key: 'none', label: 'none'}). Two sentinel keys
(NO_ASSIGNEE_GROUP/NO_LABEL_GROUP) plus a shared translateGroupLabel()
replace it with a real "No assignee"/"No label", translated into all 245
locales directly (not left as English placeholders), everywhere that group
label is rendered: server/lib/boardChartData.js (the server chart-data
loader both the live view and the exporters read from),
models/lib/chartExportRows.js (the shared PDF/Excel/data-table shape), and
client/components/boards/charts/boardCharts.js (the live Chart.js bars).
Also fixes a board report chart (reported: Burndown) rendering its export
buttons and table but no visible chart: the `<canvas>` boardCharts.js draws
into only exists once isLoading/hasNoData flip Blaze's jade conditional to
its "else" branch - a sibling reactive change driven by the SAME chartData
update the chart-building autorun also depends on, with no guaranteed
ordering between the two Tracker computations. The very first successful
data load could run the chart-building body before Blaze patched the DOM;
templateInstance.find() silently returned null, no chart was ever built,
and nothing triggered a retry. The canvas lookup is now deferred with
Tracker.afterFlush so it always runs after the DOM has actually been
patched.
Also removes three dead <link> tags in gantt.jade pointing at
gantt.css/ganttCard.css/boardCharts.css's raw source path - all three are
already loaded through the normal bundler import (client/features/gantt.js,
client/features/boards.js), and the runtime <link> to the unserved source
path 404'd as text/html, pure console noise on every Gantt page load.
Thanks to xet7 !
The Labels popup (client/lib/popup.js's global Popup singleton) was never
closed when a card's details view was closed or swapped for another card -
Blaze just destroys the cardDetails template instance, and nothing called
Popup.close()/back() in response. So the popup stayed visible after leaving
card A, and opening Labels again on card B pushed a new stack entry on top
of the stale one instead of replacing it, leaving the old entry (still bound
to card A's data) rendered alongside the new one and able to keep toggling
labels on the wrong card.
Popup.open() now resets its stack when a fresh popup (not a sub-popup opened
from within the popup that is already showing) is opened while a previous
popup is still open. Template.cardDetails remembers which card it was
opened for and, on destroy, closes Popup if it is still showing that same
card's data at the base of its stack - so closing or switching a card
dismisses its own popup without touching an unrelated one.
Thanks to rmb82 and xet7 !
Fixes#6686,
The collapsed-class assertion used jade.indexOf(')\n') with no start
offset, so it matched template(name="minicard")'s own closing paren before
.minicard( even began, slicing an empty/negative range. titleClickToEdit's
title-block boundary still referenced the pre-collapse `if showLabels`
marker instead of the new `unless minicardCollapsed` guard.
Thanks to xet7 !
The title used to render after the dates/cover/upload-progress block. It
now renders first, right after the drag handle and details-menu button, so
it stays visible regardless of collapse state.
A caret at the minicard's top-left corner - the same caret-down/caret-right
convention already used for list, swimlane and per-checklist folding, with
the same accessibility attributes (role="button", tabindex, aria-expanded)
as the per-checklist caret on the minicard itself - collapses everything
except the caret and title: dates, cover, upload progress, labels, custom
fields, assignees/members, checklists, badges, description, list name and
parent-task prefix/subtext. The details-menu button and the optional drag
handle render before the caret/collapse guard, so they stay reachable
either way.
State persists the same way list collapse already does:
Utils.getCardCollapseState/setCardCollapseState (client/lib/utils.js) check
a Session cache first, then profile.collapsedCards on the user document
(models/users.js, server method in server/models/users.js) - deliberately
with no anonymous/cookie fallback, since a public board can have far more
cards than lists and a per-card cookie entry per anonymous visitor would
grow without bound; an anonymous visitor's fold still works for the
session, it just does not survive a reload.
Thanks to xet7 !
The Calendar view drew a Start/End interval bar and a separate Due marker,
but Received never got a marker at all, and a card whose Start fell
outside the visible window got no End marker either - so a user could not
see all four of WeKan's card dates (Received, Start, Due, End) on the
Calendar. cardsReceivedInBetween/cardsEndInBetween (mirroring the existing
cardsDueInBetween) give Received and End their own labeled events.
Frappe Gantt and DHTMLX Gantt each only ever drew a single bar per card
(Start-or-Received to Due-or-End), silently dropping whichever date lost
that fallback. Both now track which underlying field each bar edge
actually represents and show all four dates - Frappe in its click popup,
DHTMLX in its hover tooltip - so Received/End stay visible even when the
bar itself only spans Start/Due.
Compared against Kanboard's Gantt (kanboard/plugin-gantt, MIT) for feature
parity: both WeKan Gantt alternatives now support drag-to-move and
drag-to-resize, persisted back to the correct field (card.setStart/setDue/
setReceived/setEnd - the same calls the Calendar's own drag handlers
already use), gated on the same board-write capability as the rest of
WeKan rather than offered to users the server would refuse. Kanboard has no
dependency arrows, view-mode switching or export; nothing to match there.
Thanks to xet7 !
Frappe Gantt was embedded below WeKan's own Gantt view on the same page.
It is now its own separate Board View menu entry and page, matching how
every other view (Swimlanes, List, Calendar, Statistics, ...) works: pick
it from the Board View menu, see only that view.
Adds a third Gantt option the same way: DHTMLX Gantt Community Edition,
genuinely MIT-licensed as of v10 (verified against the LICENSE.md text
inside the published package, not just the npm license field - the
project's own issue #2870 rejected an earlier DHTMLX Gantt proposal in
2020 for being GPL, so that distinction matters here). Zero runtime
dependencies, lazy-loaded the same way as Frappe Gantt. Unlike Frappe
Gantt's CSS, dhtmlx-gantt's package.json has no "exports" map at all, so
its CSS resolves through plain subpath resolution with no vendoring
needed. It is a page-wide singleton (`gantt`, not a class instantiated per
container), so it is torn down with destructor() on every re-render and
template destroy rather than merely cleared.
Both alternatives draw the same start/due/end task set as WeKan's own
Gantt view and export through the existing 'gantt' chart export route.
A separator now also sits between Statistics and the Gantt group in the
Board View menu, matching the existing grouping convention.
Thanks to xet7 !
Every PDF upload logged "Document search indexing failed: TypeError:
textDocument.destroy is not a function" and left that PDF's contents
unsearchable. pdfjs-dist's getDocument() returns a PDFDocumentLoadingTask;
destroy() lives THERE. Its .promise resolves to a PDFDocumentProxy, which
has no destroy() of its own - calling it on that object throws. The loading
task is now kept and destroyed instead.
Also silences "Ensure that the standardFontDataUrl API parameter is
provided" on every PDF: pdfjs-dist ships its own standard-font metrics and
CJK character maps as plain files in the installed package: point
standardFontDataUrl/cMapUrl at them via the same runtimeResolve trick
already used for the worker file, instead of falling back to an
approximation on every single PDF indexed.
Verified end-to-end against a real uploaded PDF, not just source patterns.
Thanks to xet7 !
meteor build (and the dev server) failed with "Package subpath
'./dist/frappe-gantt.css' is not defined by exports" - frappe-gantt's
package.json only exposes a "style" CONDITION on its "." export, not a
"./dist/frappe-gantt.css" subpath, so rspack's Node exports-map enforcement
rejected the dynamic import() outright, on every build.
Its CSS is vendored verbatim into frappeGanttLib.css instead (~7 KB,
unminified structure kept for a readable diff on a later upgrade) and
loaded with a plain static import, the same way gantt.css/ganttCard.css
already are for the view above it - only the JavaScript itself still uses a
dynamic import(), which is the part actually worth lazy-loading.
Two repo-wide CSS policy tests (WeKan's own font-scale variable, and
left/right -> logical-property conversion for RTL) scan every client
stylesheet and do not have a precedent for a vendored file that is shipped
byte-for-byte on purpose; both gained a narrow, explicit exclusion for
files whose own header says "Vendored verbatim from", checked against that
header so the exclusion cannot silently drift from what it claims to cover.
Thanks to xet7 !
Two full-featured, permissively-licensed charting libraries replace the
plain CSS bars used so far, chosen for a copyfree license and a minimal,
auditable dependency tree over feature richness: Frappe Gantt (MIT, zero
runtime dependencies, ~15 KB gzipped) and Chart.js (MIT, one dependency -
@kurkle/color, also MIT). Both are loaded with a dynamic import() so their
code only reaches the browser when the relevant view is actually opened.
WeKan's own hand-rolled Gantt view (the week-grid table) is kept exactly as
it is; Frappe Gantt is added below it in the same board view
(client/components/gantt/frappeGantt.js/.jade/.css), drawing the same
start/due/end task set from the board's cards, opening a card on click, and
exporting to PDF/Excel through the existing 'gantt' chart export route
(models/exportCharts.js) rather than a second pipeline for identical data.
The 10 board report chart views (client/components/boards/charts/) draw a
Chart.js bar chart instead of a stack of CSS-width divs, reusing the same
computeBarRows data normalization and the same per-chartKey export route
unchanged - only the rendering changed.
Thanks to xet7 !
The minimal server-rendered GIF-slideshow document preview (added this week
to cut dependency weight) kept failing with a bare 415 - its own
rasterization dependency chain (pdf-to-img -> pdfjs-dist's optional
@napi-rs/canvas) needed three separate fixes in a single day for a missing
package, a worker path resolved into the wrong bundle directory, and a stale
stored filename, and still left a text-only fallback as the best case for a
PDF.
Restore the previous full-featured viewer instead: office-open-xml-viewer
(MIT, canvas-based, zero runtime dependencies) renders DOCX/XLSX/PPTX
client-side, and PDF goes back to the browser's own native <embed> viewer -
simpler, zero extra dependencies, and gets the browser's own zoom/search/
print for free.
The server-side full-text search this week's change introduced is kept:
server/lib/documentGif.js now does nothing but extract plain text for the
search index (indexDocumentText, triggered in the background from
Attachments.onAfterUpload) - no rendering, no HTML, no page images - so
pdf-to-img and @napi-rs/canvas are dropped entirely (nothing rasterizes a
PDF page server-side any more) while pdfjs-dist stays, now as a direct
dependency, for its text-only extraction. Searching attachment contents from
the card search box keeps working exactly as before.
Thanks to xet7 !
After the pdf.worker.mjs fix, opening the PDF preview still failed with a
415, now logging "Attachment image stream is unavailable" from
boundedStreamBuffer: getFileStrategy(attachment, 'original').getReadStream()
returned nothing. The regular attachment download route repairs a stored
name/extension that has drifted from what is actually on disk
(normalizeStoredNameOnRead, fs-path-heal) before it reads the file;
authorizedDocument (shared by all three /document-preview/* routes) never
did, so getReadStream() could resolve the wrong path for an attachment whose
name needed that repair, even though the very same attachment downloads and
previews fine as a plain image.
Thanks to rmb82 and xet7 !
Opening the PDF slideshow viewer on an attached PDF still failed with a 415
after the previous #6685 fix, now with the real error visible:
"Setting up fake worker failed: Cannot find module
'.../_build/main-dev/pdf.worker.mjs'". pdfjs-dist's Node fake-worker
fallback locates pdf.worker.mjs relative to import.meta.url of the module
that imported it; under the bundled server (_build/main-dev,
_build/main-prod) that URL points into the bundle output, not into
node_modules, so the fallback looked for the worker beside the bundled
server.cjs and never found it - every PDF preview failed, image and text
alike, not only the rasterized-image path the earlier fix addressed.
Point GlobalWorkerOptions.workerSrc at the real on-disk file via Node's own
module resolution (the same runtimeRequire trick already used for fflate)
so pdfjs never falls back to guessing. pdf-to-img imports the same single
pdfjs-dist instance, so this also fixes its internal rasterization.
Thanks to rmb82 and xet7 !
pdf-to-img rasterizes PDF pages through pdfjs-dist's optionalDependency
@napi-rs/canvas. A Docker/Snap build that skips optional dependencies, or
lacks a prebuilt binary for its target architecture, then throws on the
very first PDF preview - "Cannot load @napi-rs/canvas", "Cannot polyfill
DOMMatrix" - which the generic catch in server/routes/universalFileServer.js
turned into a bare 415 with the real error never logged.
@napi-rs/canvas is now a direct dependency so it installs the same way
every other required package does. Rasterization is also no longer
all-or-nothing: pdfjs-dist's text extraction does not need canvas, so when
rasterizing still fails for any reason the PDF preview now degrades to
text-only pages (dropped images, kept text) instead of failing outright -
the same graceful degradation the minimal viewer already applies to an
unreadable embedded image in a DOCX/PPTX/XLSX. The three document-preview
routes now log the caught error before returning 415.
Thanks to rmb82 and xet7 !
Fixes#6685,
The native useHttpOnlyCookies resume flow only attaches Expires/Max-Age to
meteor_login_token when it can match the freshly issued token back to a
stored resume token in the database at the exact moment the cookie is
written. When that lookup misses, the cookie is written with no expiry at
all, so the browser treats it as a plain session cookie and drops it the
moment the browser closes - silently downgrading the configured 90-day
login into a same-session-only one. http.ServerResponse.prototype.setHeader
is now patched to guarantee a fallback expiry, decided by a pure, tested
helper (server/lib/loginCookieExpiry.js), whenever a Set-Cookie header for
that cookie carries neither directive.
This hardens the failure mode that best matches #6684, but has not been
confirmed as its root cause from a live browser-restart reproduction; the
issue stays open pending that.
Thanks to markusst1982 and xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Add Upcoming entry for the board report charts and Gantt/chart export
feature, and link the two entries in v11.67 that were missing their commit
links.
The Board View menu's Dashboard, Burndown, Burnup, Cumulative Flow, Control
Chart, Lead/Cycle Time, Flow Efficiency, Throughput Histogram and WIP Run
entries opened a plain "not implemented yet" page. Each now computes and
renders its chart from this board's own Cards/Lists/Activities, per
docs/Features/Reports/charts.tsv's calculation descriptions - plain HTML/CSS
bars and a data table, no new charting dependency.
Every chart page, and the Gantt view, gets "Export to PDF" / "Export to
Excel" buttons that reuse the existing card/board export renderers
(pdfDocument's line/bar builder, createWorkbook's Excel styling) through the
same public-board / authToken / logged-in-user auth gate every other export
route already uses.
Completion date is card.endAt || card.archivedAt (WeKan has no dedicated
"Done" list flag); WIP Run's limit line only draws when a list's own WIP
limit is enabled (no invented board-level schema); Flow Efficiency's
"active" time is card.spentTime (WeKan does not track per-list queue time).
Each deviation from charts.tsv is documented where the calculation is.
models/lib/chartCalculations.js (20 tests), models/lib/chartExportRows.js
(8 tests) and the export routes' auth shape (10 tests) are covered by
tests/chartCalculations.test.cjs, tests/chartExportRows.test.cjs and
tests/chartExportRoutesAuth.test.cjs; tests/boardViewMenu.test.cjs is
updated for the now-real views. Not verified here: actual Blaze rendering
and generated PDF/XLSX bytes (no browser/Meteor runtime in this
environment) - matched syntactically against statsView/timeView and the
existing exporters.
models/server/ExporterZip.js still called archiver the v7 way -
require('archiver')('zip', {...}). archiver@8 is ESM-only and exports
classes with no callable default, so that call threw synchronously before
exportZip's route wrote any response header, and safeRoute answered a bare
500 with no detail - every "export board -> .zip" request, for every
board. server/methods/backup.js hit the identical break earlier and
already fixed it with `new ZipArchive({...})`; this call site was missed.
Fixed the same way, with a regression test that also scans the tree for
the same dead API shape.
Thanks to the reporter and xet7 !
The reporter's DEBUG=true server log (getToken/getUserInfo repeating six
times in under twenty seconds, a fresh access token each time) matches the
exact race commit 89682c251 already fixed: oauth2-login-style redirect with
oidc-redirection-enabled true re-firing the auto-redirect on the identity
provider's bounce-back render before the prior login had finished. That fix
landed before v11.62, several releases back; the reporter's build predates
it. tests/oidcAutoRedirectLoop.test.cjs (6 checks) still passes against
current source. No application code changed; asked the reporter to upgrade.
Thanks to Alishara and xet7 !
Fixes#6681,
Add Upcoming section summarizing the newest node-patches,
mongo-tools-patches and mongosh-patches build improvements not yet
reflected in the WeKan changelog.
The test still clicked the minicard's own "Show on Minicard" menu entry
(.js-show-on-minicard), which no longer exists: that setting moved to
Board Settings / Card, reached from the board's cog menu, as part of
this session's #6680 follow-up. Updated the test to open it from there
instead - the underlying checkbox
(.js-field-has-creator-on-minicard) and its behavior are unchanged.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Reported: checkmk warned "/tmp/.mount_wekan.OhaGOG ... 100% used"
because the AppImage runtime's own read-only squashfs mount landed on a
small /tmp (a squashfs mount always reports 100% used regardless of
size, so this was really "/tmp is too small for the AppImage", not a
leak).
The AppImage runtime mounts itself under $TMPDIR/.mount_<name>.<random>
(defaulting to /tmp) before AppRun ever runs, so the very first launch's
mount cannot be redirected from inside AppRun. AppRun now re-execs
itself once per launch with TMPDIR set to WRITABLE_PATH/app when the
caller has not already chosen a TMPDIR, so every launch from then on
mounts there instead - and, on that same first launch, sweeps out any of
WeKan's own orphaned .mount_*ekan* directories left in /tmp by an
earlier, uncleanly-killed run (a live one, matched against /proc/mounts,
is never touched).
AppImage-only: no other WeKan platform (Docker, snap, .deb, the bundle
zip) FUSE-mounts itself the way an AppImage does, so none of them are
touched. tests/appImageRuntime.test.cjs pins the relocation, the
once-per-launch/explicit-TMPDIR guards, and that only orphaned mounts
are removed.
The upload path-traversal guard was logging under the pre-existing
PathBleed key (a different, already-published advisory,
GHSA-4mxf-m8pq-xc9p about avatar versions.path and board export) - it
now has its own UploadPathBleed key, so the two incidents are not
conflated on the public Hall of Fame page or in Admin Panel / Problems.
The two High advisories (missing Avatars.protected, unauthenticated
serveLegacyAvatar) now also log a blocked attempt, under new
authz.avatar-protected/PortraitBleed and
authz.legacy-avatar/RelicAvatarBleed keys, matching the site entries
added at .tools/wekan.fi.
tests/securityRegressionCoverage.test.cjs's inventory and
tests/attachmentAvatarSecurityAdvisories.test.cjs are updated so all four
names (WipeBleed, UploadPathBleed, PortraitBleed, RelicAvatarBleed) are
recognized as GUARDED, matching the published Hall of Fame count.
CRITICAL - Unauthenticated Arbitrary File Write via Path Traversal in
Attachment Upload namingFunction: Attachments overrode ostrio:files'
sanitize() to an identity function and used the client-supplied fileId
verbatim as the on-disk file name, so an anonymous upload with
fileId: "../../../../tmp/pwn" could write attacker-controlled content
anywhere the WeKan process can write. sanitize() is restored to the same
whitelist models/avatars.js already used for the same tokens, and
namingFunction now validates the (sanitized) fileId against the ObjectId
shape WeKan itself generates, regenerating a fresh one otherwise.
CRITICAL - Unauthenticated DDP Methods _FilesCollectionRemove_attachments/
_FilesCollectionRemove_avatars Allow Instance-Wide Deletion: ostrio:files
registers its own remove method, gated only by allowClientCode and never
routed through Attachments.allow/Avatars.allow (those only gate the
ordinary Mongo .remove() call). Attachments had no onBeforeRemove at all
and Avatars' unconditionally returned true, so any anonymous DDP caller
could pass selector {} and wipe every attachment or avatar on the
instance. Both now require this.userId and check every matched file:
attachments need the caller's board-write access, avatars need ownership
or site-admin status.
High - Avatars Collection Lacks `protected` Callback: unlike Attachments,
Avatars never set `protected`, so ostrio:files' own library-native
download route (its _checkAccess defaults to allowing everything when
`protected` is unset) served any avatar to anyone, bypassing
isAuthorizedForAvatar entirely. Avatars.protected now mirrors
Attachments.protected: any authenticated caller, or an anonymous one only
when the avatar's owner is on a public board.
High - serveLegacyAvatar Serves Legacy CollectionFS Avatars Without Any
Authentication: both call sites in server/routes/avatarServer.js streamed
a legacy avatar to any caller who knew its old filerecord id, one of them
(/cfs/files/avatars) with no check at all. Both now require an
authenticated caller (isLegacyAvatarAuthorized) - legacy records carry no
owner/board link that can be safely checked for the public-board
exemption current avatars get, so this is deliberately narrower rather
than reusing that exemption on an unverifiable claim.
Both CRITICAL fixes log a blocked attempt through the shared security log
(new authz.file-remove/WipeBleed catalog key, and the existing
authz.file-path/PathBleed key), so Admin Panel / Problems shows an
attempt was made. tests/attachmentAvatarSecurityAdvisories.test.cjs pins
all four fixes and the negative cases (no dangling anonymous bypass, no
regression to the legitimate admin avatar-delete and public-board
redirect flows).
Both are still reachable by dragging the resize handle (unless Board
Settings / List or Board Settings / Swimlane has locked that), and the
board-wide fixed-width value now lives in Board Settings / List - a menu
entry for the same thing was a second place to look for it. The
underlying popups (setListWidthPopup, setSwimlaneHeightPopup) are
untouched, only the menu entries that opened them are removed.
Removing "Set width" left its own group empty, so the group (and its
enclosing hr) is removed entirely. Removing "Set Swimlane height" left
"Select color" as the only row of its group, so that group's hr moves
inside the same isBoardAdmin check as the color entry itself, rather than
leaving a dangling hr (or an empty list) for a non-admin.
The hr between the field list and "Add custom field" was unconditional,
so with no custom field on the board yet it drew a rule with nothing
above it to separate. It is now conditional on board.customFields.length.
CSS order on the grid items, not a markup change: column 1 (card) and
column 2 (minicard) keep their original DOM order, so the show-card-only/
show-minicard-only nth-child hiding rules still target the right element
regardless of side. Only the visual position of the two swaps; Description
(column 3) gets an explicit order too, so it is not pulled in front by
the default order:0 an unordered item would otherwise share.
The column headings above the settings table (commit 02025aa6c) were
removed because the popup used to flow its rows into several side-by-side
columns whenever only Card or only Minicard was shown, so the heading sat
above the first of those columns and read as if it named that one alone.
Board Settings / Card always shows both columns in a single list of rows
now (no side is passed, so that multi-column masonry layout never
applies), so the ambiguity that got the heading removed is gone. It is
back as an ordinary .card-settings-row - not the old separate
.card-settings-grid/sticky-header markup - so the same CSS that hides a
column for the still-supported side="card"/"minicard" case hides the
matching heading with it, and personalOnly (what a non-admin gets) hides
the whole heading along with every other non-personal row. All three
labels reuse existing, already-translated keys (show-on-card,
show-on-minicard, description).
#6680 follow-up. Three reorganizations of where board settings live,
grouped under Board Settings (the board's cog menu), with an <hr> above
and below the new group of three:
- The list-width and swimlane-height resize-lock toggles and the
board-wide "same width for all lists" toggle move out of the header
and into Board Settings / Swimlane and Board Settings / List.
- Minicard and Card settings (the shared board-wide settings table) move
back into Board Settings / Card. They previously lived split across
the card's own menu ("Show on Card") and the minicard's own menu
("Show on Minicard"); both entries, their popups, and the
cardMenuSource module that only existed to tell those two menus apart
are removed. A non-admin still reaches the one PERSONAL row in that
table ("Labels text") through the same entry, via personalOnly.
Swimlane and List stay board-admin only (the resize locks already were);
Card is open to any board member, matching who could reach it before.
All three reuse existing translations ('swimlane', 'list',
'card'/'card-settings') via Popup.open's titleKey rather than adding new
*Popup-title keys.
tests/boardSettingsSwimlaneListCard.test.cjs pins the new layout;
tests/listSwimlaneResizeLock.test.cjs, tests/headerIconsCollapse.test.cjs
and tests/popupTitles.test.cjs are updated for what moved.
A generic .list-header .list-header-name rule sets min-width: 56px for
ordinary (non-collapsed) list headings. min-width is a separate property
from width, so it survives the cascade even where a more specific
collapsed-list rule wins on width, clamping the rotated title's box to
56px regardless of the 30px collapsed column - offsetting it to the right
of the caret above it. Override min-width back to 0 in every collapsed-
title h2 rule (the plain/mobile-view rule, the desktop :not(.mobile-view)
rule, and its three @media min-width duplicates) so width: 100% of the
narrow column actually applies.
Verified with a Playwright measurement of the caret's and title's
horizontal centers matching after the fix.
Two real breakages, both caught by the full node-suite run rather than by
the four tests added alongside the feature itself:
1. The collapsed state was appended into #header-quick-access's own
`class="{{themeColorClass}}"` binding, which broke
tests/globalThemeColor.test.cjs's exact count of elements using that
binding unmodified. Moved to a separate `data-header-icons-collapsed`
attribute instead, and updated header.css's selector to match on it.
2. Wrapping +boardHeaderButtons/+allBoardsHeaderButtons/+boardViewMenu/
+allBoardsViewMenu/+adminPanelTabs in a span.js-header-collapsible-icon
broke four tests (allBoardsPage, boardHeaderOneLine, headerBars x2) whose
regexes expected each inclusion to sit directly on the line after its
`if isBoardPage`/`if isAllBoardsPage`/`if isAdminPanel` guard. Updated
each regex to expect the new wrapper span in between.
tests/headerIconsCollapse.test.cjs itself is updated for the data-attribute
shape. Full node-suite run is back to the two pre-existing, unrelated
failures (buildScriptParity, gitMirrorUpdateScripts - missing build
scripts in this sandbox).
Thanks to xet7.
toggle-header-icons-collapsed was added to en.i18n.json only in commit
d1b01924e; translate it into all 232 other locale files, per this repo's
translation policy (CLAUDE.md - every language gets translated, not just an
English placeholder). A handful of lower-resource languages (Klingon,
Wolof, Cherokee, and similar obscure/under-resourced ones) were translated
with lower confidence from cognates and kanban-adjacent vocabulary rather
than fluent native phrasing, and will be replaced automatically by a real
Transifex human translation when one arrives.
node releases/translations/fill-translations.mjs --missing now reports 0.
Thanks to xet7.
A single button, right after the board title (inside the same .home-icon
wrapper), that hides every icon from the mobile/desktop toggle through the
notification bell: mobile/desktop mode, drag-handles toggle, the three
board-wide resize-lock icons, the starred-boards group, create-board, the
board/all-boards header buttons, the view menu, the Admin Panel tabs, and
notifications.
Purely a per-viewer display preference, not persisted anywhere - a plain
Session var (wekan-header-icons-collapsed), the same shape as mobileMode()
right beside it in header.js, not a board setting like the resize locks.
Every icon in that range gets a shared .js-header-collapsible-icon marker
class; the four `+templateName` inclusions and +notifications cannot carry
a class of their own, so each is wrapped in a `span.js-header-collapsible-
icon` that stays `display: contents` outside the collapsed state, so
introducing the wrapper does not change how those icons behave as flex
items of #header-quick-access when nothing is collapsed.
`#header-quick-access.header-icons-collapsed .js-header-collapsible-icon`
is the one CSS rule that actually hides them.
tests/headerIconsCollapse.test.cjs pins the button's position, the
Session-var (not board-setting) shape, that every icon in the range is
marked and nothing outside it is, and both CSS rules.
Thanks to xet7.
The previous fix (385f36e91) over-corrected: making .list-rotated grow to
fill the whole (often 540px) collapsed column and centering within that
full height moved the title far from the collapse-toggle/drag-handle at the
top (.tools/collapse2.png) - "centered" meant horizontally, across the 30px
column width, not vertically down the whole column.
Reverted both rule sets to exactly how they shipped (sized to their own
content, near the top) and kept only the one real fix: the desktop rule
that actually wins (.list.list-collapsed:not(.mobile-view) ...) had
`text-align: start`, leaving the vertical text flush to one edge instead of
centered across the width. Changed to `text-align: center`, matching the
plain/mobile-view rule, which already had it and was never broken.
tests/collapsedListTitleCentered.test.cjs is rewritten for this shape:
pins the text-align fix, and negatively pins that neither rule set grows
or centers across the full column height any more.
Thanks to xet7.
The title used to sit near the TOP of a tall (540px) collapsed list, with
empty space below it (.tools/collapse.png), on the desktop rule that
actually wins (.list.list-collapsed:not(.mobile-view) ...): it explicitly
pinned the title with `flex: 0 0 auto` and `align-self: flex-start` and
never grew to fill the space left after the collapse-toggle/drag-handle.
The plain (mobile-view) rule had the opposite bug - `flex: 1` fighting its
own explicit `height: auto !important`, which also kept it from growing.
Fixed both to grow (flex: 1 / flex: 1 1 auto) and center (display: flex;
align-items/justify-content: center). Centering the title text itself
inside its now-correctly-sized box needed one more fix verified with a
Playwright screenshot of a minimal reproduction: shrinking the <h2> to its
own content (so the parent's centering has something to center) rendered
NO TEXT AT ALL for a vertical writing-mode block box with width/height:
auto in a real browser. The <h2> stays 100%/100% of its parent instead and
centers its own text run with flex (display: flex; align-items/
justify-content: center on the h2 itself), which measured correctly in
both the plain and :not(.mobile-view) rule sets.
tests/collapsedListTitleCentered.test.cjs pins the fixed values in both
rule sets, comment text stripped first so an old value quoted in a
"this used to be X" explanatory comment cannot pass as evidence X is gone.
Thanks to xet7.
startResize() already refused to act while
board.getSwimlaneHeightResizeLocked() was true, but the handle itself - and
its blue drag-height line on hover - stayed visible, which reads as broken
rather than locked. Hide it entirely while locked, the same way
client/components/lists/list.js already hides .js-list-resize-handle for
its own lock, wrapped in a tpl.autorun so toggling the lock updates it live.
Thanks to xet7.
Same shape as the two resize locks beside it: fa-check when the board-wide
same-width mode is on, fa-ban when it is off, instead of a static fa-columns
with a separate "active" background class. Dropped the "active" class
entirely - the icon swap already says which state it is in, and that class
happened to match a stale guard (tests/boardExportScope.test.cjs) written
for a different, unrelated bug: an unconditional tick beside an
`{{#if}}active{{/if}}` class outside a `ul.checkable` list used to mean an
always-on tick that lied about the row's state. This button's tick is not
unconditional - it is the reactive fa-check/fa-ban pair - so the class was
simply redundant, not a repeat of that bug.
Thanks to xet7.
The list-width and swimlane-height resize locks used their own fa-lock/
fa-unlock icons. Match .js-toggle-desktop-drag-handles instead: fa-check
when resizing is allowed, fa-ban when this lock has denied it - the same
allowed/denied icon language already used right beside them in the header.
Thanks to xet7.
Adds three independent per-board toggles in the top header, right of the
drag-handles toggle:
- list-width resize lock: left-right arrow icon plus a lock/unlock icon
that flips when clicked. Locked, the drag-resize handle between lists
does nothing for anyone on the board.
- swimlane-height resize lock: same shape, up-down arrow icon, gates the
drag handle at the top of each swimlane.
- "same width for all lists": the board-wide equivalent of the existing
per-user "Set width" popup's fixed-width mode. An admin can force every
list on the board to one shared width for every viewer, overriding each
member's own personal choice while it is on.
All three are board settings (models/boards.js: listWidthResizeLocked,
swimlaneHeightResizeLocked, sameWidthForAllLists, sameWidthForAllListsValue),
shown only on a board page and only to board admins (client) - turning a
toggle itself on/off is admin-only on the server too
(server/permissions/boards.js's default allowIsBoardAdmin rule). Dragging
the shared same-width VALUE, though, is allowed for any board member with
write access, via a new sole-field Boards.allow rule
(canUpdateBoardSameWidthValue in server/lib/utils.js) shaped exactly like
the existing canUpdateBoardSort rule: it approves a modifier ONLY when
sameWidthForAllListsValue is the one field touched, so a lower-privilege
member can never smuggle another board field into the same update.
client/components/lists/list.js's canResizeList/effectiveListWidth/
saveListWidth and client/components/swimlanes/swimlanes.js's resize
startResize are the actual enforcement points - the lock is checked before
a drag can start, and the board-wide fixed width takes priority over each
viewer's personal fixed-width mode.
Added the 3 new tooltip strings to all 235 locale files (not just English),
per this repo's translation policy; a handful of lower-resource languages
(Klingon, Wolof, Cherokee, and similar) were translated with lower
confidence and will be replaced by a human Transifex translation
automatically when one arrives. tests/listSwimlaneResizeLock.test.cjs pins
the schema, the header wiring, the permission rule shape, and that each
resize handle actually checks its lock.
Thanks to Hallsie and xet7.
Fixes#6680,
The maintainer restructured the top of CHANGELOG.md by hand: "# Platforms"
and "# TODO Later" are no longer their own top-level headings. Both are now
<details> blocks nested inside a single "# Status" heading, which also
gained a "More status info" block linking https://wekan.fi/status/, and the
platform/install links moved into their own "Newest WeKan at these
platforms" details instead of sitting directly under the heading.
Updated CLAUDE.md's/AGENTS.md's "file's shape" spec and every other mention
of "# Platforms"/"# TODO Later" as literal headings to describe the new
nesting. tests/changelogFormat.test.cjs's structural checks all located
"# TODO Later" by exact heading text, which no longer exists; replaced with
a shared `todoAt` lookup of `<summary>TODO Later</summary>` used everywhere
those checks anchor themselves. releases/changelog-archive.mjs needed no
change: it already finds the header by "everything above the first release
heading" and the "Older releases:" bullet by content, not by position
relative to "# Platforms" specifically.
Thanks to xet7.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
This reverts commit 8614949580.
Restores the per-user/per-list resizable list width (drag-resize handle, the
"Set width" list-menu popup, the board-settings "Personal list width"
sidebar toggle, and the auto-width mode) and the "Set swimlane height"
popup, at the maintainer's request.
Thanks to xet7.
The maintainer removed this table by hand from the current month's
CHANGELOG.md - it was tried right under each release's "In short" summary,
then moved to a "Binaries in these bundles" label at the end, and both times
made every release's entry mostly a giant table nobody read. Update
CLAUDE.md/AGENTS.md's CHANGELOG spec and the docs template to stop
prescribing it, and change tests/changelogFormat.test.cjs's binaries-table
test into a negative one. tests/newestBundledBinaries.test.cjs is updated to
verify the same data instead through the GitHub Release notes, which
releases/provenance-table.sh still builds fresh from
releases/record-provenance.sh's recordings on every release - that mechanism
is unchanged, only the CHANGELOG copy is removed.
Thanks to xet7.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
DOCKERHUB_AUTH/QUAY_AUTH are scoped for docker login/image push, and neither
registry grants a push-scoped token the rights a repository-description
write needs - v11.62's release-all.yml run already showed this step fails
with 403 even though the image itself publishes fine (the previous commit
turned that into a non-fatal warning rather than fixing the underlying
permission gap). The maintainer now updates both registries' overviews by
hand, so remove the step entirely rather than keep maintaining a permission
workaround for it. tests/dockerRegistryOverviewSync.test.cjs is removed with
it, and its curl -X PATCH/-X PUT exemption in
tests/releaseDownloads.test.cjs is reverted since no such calls remain.
This also resolves GitHub code scanning alerts #523-#525 ("Incomplete URL
substring sanitization"), which flagged the now-deleted test file's URL
substring assertions.
Thanks to xet7.
v11.62's release-all.yml run failed the whole "docker" job with 403 from both
Docker Hub and Quay.io on the repository-overview PATCH/PUT calls added
earlier, even though the image itself had already been built, pushed and
verified pullable by the steps before it. DOCKERHUB_AUTH/QUAY_AUTH are scoped
for `docker login`/image push, and neither registry grants a push-scoped
token the broader (account-owner / repo-admin) rights a description write
needs - so the sync step's own `exit 1` failed a job that had, in fact,
already published, which blocked every downstream job gated on
`needs.docker.result == 'success'` (the Helm chart update).
A stale repository description is not worth failing a release over: the sync
step now reports each registry's failure as ::warning:: rather than
::error::, drops the shared `fail` flag, and always exits 0. Each registry
is still attempted independently. Logs (.tools/wekan11) confirm the actual
image push, manifest verification and anonymous-pull checks all succeeded
for v11.62; only this cosmetic step was ever the problem.
Thanks to xet7.
tests/releaseDownloads.test.cjs requires every curl in the release workflows
to go through fetch.sh's retry/backoff, since an unretried download has lost
a release to a transient outage before. The Docker Hub/Quay.io overview-sync
step added earlier uses curl -X PATCH/-X PUT directly, same as the adjacent
-X POST login call already exempted: failing to update a repository
description does not lose a release the way a failed binary download does,
and the step already reports and isolates its own failure. Extend the
existing -X POST exemption to also cover PATCH and PUT.
Thanks to xet7.
CHANGELOG.md no longer carries an empty "# Upcoming WeKan (R) release" section
with an "In short: nothing here yet." placeholder between releases.
release-all.sh used to auto-create one immediately after renaming a release
(via the now-deleted releases/changelog-open-next.mjs), so the file always
had a section that said nothing until the first real entry replaced it.
Add the Upcoming section yourself, by hand, the moment there is a real entry
for it, using the skeleton at
docs/DeveloperDocs/Changelog-Upcoming-Template.md. What actually prevents an
entry from landing inside an already-published release -
tests/changelogEntriesBelongToTheirRelease.test.cjs asking git which commits
a release contains - never depended on the placeholder existing first, so
removing it costs nothing.
Also reorders each release section: the binaries table used to sit right
under the "In short" summary; it now comes LAST, under its own "Binaries in
these bundles:" label, after every content subsection and right before the
closing "Thanks to above GitHub users" line. A reader opens a release to see
what changed; the platform/SHA256 table is reference material, not the
second thing anyone reads.
Updated CLAUDE.md/AGENTS.md's CHANGELOG format spec and
tests/changelogFormat.test.cjs to match both changes, and
tests/buildScriptParity.test.cjs now that changelog-open-next.mjs is gone.
Thanks to xet7.
The next release version was computed by measuring the gap between the two
newest "# vNN.MM" headings in CHANGELOG.md and re-applying that same gap,
instead of always advancing by one. That is not self-correcting: if a release
number was ever prepared and never published, and its CHANGELOG section was
deleted outright instead of renamed back to "# Upcoming WeKan (R) release"
(this script's own documented recovery for a release that never published),
the two remaining headings were left 2 apart. The script read that as "the
cadence is +2 now" and reapplied it every following release, turning one
incident into a permanent, ever-widening habit of skipping a number - exactly
how v11.56 -> v11.58 -> v11.60 -> v11.62 happened, silently skipping v11.57,
v11.59 and v11.61 (v11.33 and v11.54 were skipped by the same bug earlier).
The step is now a fixed +1 with no history lookup, and the other code path
(resuming an already-renamed release) hard-fails instead of printing
"proceeding anyway" when the newest heading is not exactly +1 from the
previous one, so a future gap is caught before it can be built on.
tests/releaseAllVersionStep.test.cjs pins the fixed +1 step and the hard
failure. The GitHub workflow itself (release-all.yml) needed no change: it
only ever uses the old_version/new_version this script hands it and never
computes a step of its own.
Thanks to xet7.
Time spent summary moved out of the Statistics view into its own Time view,
leaving statsView.jade with one .stats-view-table section (board status)
instead of two. The Playwright test still expected 2 tables and failed on
every browser; update it to expect 1.
Thanks to xet7.
.meteor/release was bumped to METEOR@3.5.2 but Dockerfile's own
METEOR_RELEASE still said METEOR@3.5.2-rc.0, so
tests/releaseVersionConsistency.test.cjs failed with a version mismatch.
Thanks to xet7.
Neither registry updates its long-form repository description on its own, so
the overview shown on the repository page had drifted from what README.md
documents. Add a step to release-all.yml's docker job, after the multi-arch
image is built, pushed and verified pullable, that pushes README.md as the
overview: Docker Hub via login-for-JWT then PATCH full_description, Quay.io
via PUT description, reusing the DOCKERHUB_AUTH and QUAY_AUTH secrets already
decoded for docker login. GHCR needs no call since a linked package mirrors
its repository's README automatically. Add
tests/dockerRegistryOverviewSync.test.cjs to pin the endpoints, request
bodies, ordering and that no token is ever echoed.
Thanks to xet7.
.tools/wekan10's downloaded run logs showed "second run: WeKan answered
on port 8080 on its first attempt." print successfully, immediately
followed by "Process completed with exit code 1" - no thrown error
anywhere in between.
taskkill.exe (unlike a PowerShell cmdlet) sets $LASTEXITCODE, which
$ErrorActionPreference does not touch - that only governs PowerShell's
own errors, not a plain exe's exit code - and `pwsh -Command` exits with
whatever $LASTEXITCODE last held when the script itself never calls
`exit`. `taskkill /IM ferretdb.exe` (no matching process is a normal,
harmless outcome on the "second" run, once the first run's FerretDB is
already gone) was the LAST external command the whole step ran, so its
nonzero "no such process" exit code alone failed the step.
Reset $LASTEXITCODE after every taskkill call in this workflow whose own
exit code is not being checked - the same latent bug was present in the
"Free ports used by the packaged EXE" step's port-cleanup loop too,
which could fail the same way if the last PID it tried had already
exited between netstat and taskkill.
Thanks to xet7.
An earlier version hardcoded the English word itself inside the
parentheses (e.g. "(Burndown)"), so on an otherwise fully translated
menu these ten entries read as a leftover bug rather than a "coming
soon" marker - the page each one opens was already correctly translated,
since its own title uses the same key (.tools/board-view.png: Finnish
throughout except this one menu). The literal parentheses are what say
"not implemented yet"; the word inside them is now translated like every
other entry, through the exact key the placeholder page's title uses.
Thanks to xet7.
Today/Previous/Next were their own group under the title, with the
Day/Week/Month view toggles in a third, CENTER group that pushed
everything onto a second row (.tools/calendar.png). All the buttons now
sit together in one group on the right of the title, which stays alone
on the left and is vertically centered against them - WeKan's global
`h2 { margin: 0 0 7px }` otherwise offset the title (an <h2>) from that
row.
Thanks to xet7.
The search input, Search button, pagination buttons and the two toggle
buttons sit in one flex row with align-items: center - but a flex child
never shrinks below its own content's minimum height no matter what the
container measures, so the Search button's bold label pushed it visibly
taller/lower than the search input beside it (.tools/button-center.png).
Every control now shares one explicit border-box height (34px) with
line-height: 1, so there is nothing left for align-items: center to fail
to center.
Thanks to xet7.
The "wrap card titles" and "group by swimlane" toggle buttons had bare
one-word tooltips ({{_ 'card'}}, {{_ 'swimlane'}}) that said neither what
clicking them does nor which of the two states is currently on. Each now
has a state-aware tooltip/aria-label ("Card titles wrap to multiple
lines. Click to truncate them with an ellipsis instead." and the same
shape for swimlane grouping), translated into all 234 locales.
Thanks to xet7.
With oauth2-login-style redirect and OIDC_REDIRECTION_ENABLED, the browser
looped between WeKan and the identity provider until the provider started
rate-limiting the repeated /authorize requests.
Template.userFormsLayout.onCreated (client/components/main/layouts.js)
fired the auto-redirect unconditionally on every render. Meteor's
redirect-style OAuth has no dedicated callback route - the identity
provider's callback bounces the browser back to this SAME sign-in page -
and the login method that follows a successful callback completes
asynchronously, racing this template's own re-render. When the
auto-redirect check ran before that login had finished, it saw "not
logged in yet" and fired a brand new navigation straight back to the
provider, forever.
Fixed with a one-shot sessionStorage flag (client/lib/oidcAutoRedirect.js)
that survives the full-page round trip to the provider and back, so the
bounce-back render does not re-fire the redirect. Cleared on both login
success and login failure (config/accounts.js), so a later logout, or a
genuine error, can still trigger the auto-redirect again rather than
leaving the sign-in page permanently stuck the other way.
Thanks to Alishara and xet7 !
Fixes#6681,
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
The prev/next page buttons were plain white with a grey border, unlike
the blue "Search" button right next to them in the same control row -
the two read as different UI families instead of one toolbar
(.tools/table-view screenshots).
Thanks to xet7.
<hr> between Gantt and Dashboard, matching the menu's existing grouping.
Dashboard now shows the same hardcoded, untranslated "(Dashboard)" label
the other nine not-yet-built views already carry - it was translated by
oversight, which said the view was finished when it is a placeholder page
like the rest of them.
Thanks to xet7.
List width is now a single hardcoded constant (models/lib/listWidth.js,
240px) applied to every list on every board for every viewer. This
replaces the #5659/#5729/#6409 model built up over time: a personal
per-user width, a per-list shared width, a viewer-toggled "same width for
all lists" mode, and a viewer-toggled auto-width mode. All of it - the
"Set width" list-menu popup, the board-settings "Personal list width"
sidebar toggle, the drag-resize handle, and every schema field and Meteor
method behind them - is removed rather than left dead.
The "Set swimlane height" menu popup goes too, as a redundant text-input
alternative to the working drag-resize handle from the swimlane-resize fix
earlier this release; that drag handle itself is untouched.
Two knock-on fixes this surfaced: models/wekanCreator.js was still mapping
the now-removed allowsPersonalListWidth/autoWidth board fields on WeKan
JSON import, which would have failed schema validation on any import; and
the CloneBleed security-regression test's applyListWidth sub-suite tested
a method that no longer exists, replaced with a comment pointing at
tests/listWidthDefaults.test.cjs's negative coverage of the removal.
tests/listWidthPopupLayout.test.cjs and
tests/playwright/specs/38-fixed-list-width.e2e.js tested only the removed
feature and are deleted outright; listWidthDefaults.test.cjs and
listWidthDuringDrag.test.cjs are rewritten/adjusted for the new model.
Thanks to xet7.
Both are `a` toggles in the "Set width" popup (setListWidthPopup) with no
display rule of their own, so the browser default (inline) put them side
by side on one crowded line (.tools/same-width.png) instead of stacked
rows like the rest of the popup.
Thanks to xet7.
<hr> separators, matching the right sidebar's own hr-separated groups:
one between Table and Calendar, one between Time and Statistics.
Nine views with no implementation behind them yet (Burndown, Burnup,
Cumulative Flow, Control, Cycle Time, Flow Efficiency, Lead Time,
Throughput Histogram, WIP Run) show a hardcoded "(Name)" label instead of
a translated one - translating them as if they were finished feature
names, like every other entry, would not say in any language that the
view behind them is just a grey placeholder page. Dashboard is left
translated; it is not on the maintainer's list of nine.
Thanks to xet7.
Document this batch under Upcoming: the Board View menu reorder and its
new placeholder/Time views, the dependency-line/collapsed-list bleed fix
on swimlane resize, and the collapse-caret positioning fix.
Thanks to xet7.
The caret rendered as a plain in-flow sibling before the title, which put
it on the row with the card count and the +/menu icons - visually
unrelated to either the title it collapses or that menu. Nesting it inside
the title heading was tried first and reverted: that heading carries
js-open-inlined-form/is-editable, so a click on the caret bubbled up and
opened the rename form instead of collapsing the list (.tools/list1).
Fixed by floating the caret to the START of the header's top content line
- list.css already floats .list-header-menu (the hamburger/+ icons) to the
END of that same line - so the caret lands level with that menu, at the
header's top corner: the left edge for LTR, the right for RTL, from the
logical float value with no extra rule needed. The collapsed state is
unchanged: its caret stays a sibling before .list-rotated, absolutely
positioned against .list-header as before.
Thanks to xet7.
headerBars.test.cjs read a fixed 700-character window after
boardViewName() to check every view has a translated tooltip name; that
window was sized for the original six views and silently stopped covering
the eleven added since (c11c1e17f), so it could not have caught them being
missing there.
Thanks to xet7.
Two independent causes (screenshots in .tools/drag):
1. `.swimlane.swimlane-resizing` forced `overflow: visible !important` for
the whole drag, so a collapsed list (a fixed 540px tall, list.css) kept
painting past a swimlane being dragged shorter, on top of the swimlane
below it. Now `hidden`, matching what the swimlane clips to once the
drag ends anyway.
2. dependencyOverlay.js (the "red string" dependency-line SVG) only ever
redraws on scroll or a window resize; changing a swimlane's own height
via drag fires neither, so a line kept the coordinates a card had BEFORE
the resize - stale positions that can lie on top of the next swimlane
once the real card is scrolled/clipped out of view. Fixed by (a)
swimlanes.js dispatching a dedicated event on every height change, which
the overlay listens for, and (b) the overlay no longer drawing to/from a
card with no on-screen area left once every clipping ancestor is
accounted for. A line between two cards in the SAME now-shrunk swimlane
disappears when its card does; a line to a DIFFERENT, still-visible
swimlane's card is unaffected, since that card's own visibility is
checked independently - dependencies that genuinely cross swimlanes are
supposed to be drawn there.
Thanks to xet7.
New order top to bottom: Swimlanes, Lists, Table, Calendar, Time,
Statistics, Dashboard, Burndown, Burnup, Cumulative Flow, Control, Cycle
Time, Flow Efficiency, Gantt, Lead Time, Throughput Histogram, WIP Run -
each with its own font-awesome icon. The ten views with no implementation
yet get a real grey page (client/components/boards/chartPlaceholderViews.jade)
titled like their menu entry, with a shared "not implemented yet" note,
instead of a menu item that opens nothing.
"Time spent summary" moves out of Statistics into its own new Time view
(timeView.jade/.js), which keeps the same boardStatus subscription
Statistics already used.
Two places had to learn every new view or switching to one silently failed:
models/users.js's profile.boardView schema only allowed the original six
values, so the server rejected Meteor.call('setBoardView', ...) for any new
one with a 400; and boardHeader.js's tooltip name map fell back to a
generic label for the same ones. tests/boardViewMenu.test.cjs pins the
menu order, that every entry has an icon/handler/isView* helper/placeholder
template, AND both of those - the schema and the tooltip map - against the
same view list, so this cannot drift out of sync silently again.
Thanks to xet7.
Document this batch of work under Upcoming, and record under TODO Later
what it deliberately left for later: Jira, Kanboard, NextCloud Deck,
OpenProject, Asana and Zenkit are still the thin best-effort stubs from
when the shared import/export plumbing landed, each needing its own
fixture/spec pass the way GitHub just got one; and further formats (the
Leo literate editor's .leo outline format and others) were not researched
or built, each costing roughly what Markdown just cost including a new
string across all 234 locales.
Thanks to xet7.
The GitHub/Gitea/Forgejo issue importer (models/lib/externalParsers.js)
mapped only a title, description, one assignee and a due date, silently
dropping everything else. It now also carries a second-and-later assignee,
a milestone title, a non-"completed" state reason and embedded comments
(as tags/description, since the shared Kanboard shape has no field for
them), and returns an `unsupported` list of what it genuinely could not
place - the `{ normalized, warnings, unsupported }` contract from
docs/Features/ImportExport/Format-Coverage.md, flattened onto the existing
board/columns/swimlanes/tasks shape so the KanboardCreator call site in
models/import.js is unaffected.
Markdown is a new import/export format: the "## List name" / "- [ ]"/"- [x]"
task-list convention several markdown-kanban tools use (Obsidian Kanban and
similar) - a plain bulleted list with no checkboxes still imports as open
cards. models/lib/markdownKanbanFormat.js holds the pure formatter (no
Meteor import of its own, so it and the parser are unit-testable without a
server); models/lib/externalParsers.js's parseMarkdownKanban is the import
side. Wired into the import source list and the export menu; the export
route serves plain text/markdown rather than JSON, since the whole point is
a file readable/editable directly or opened by another markdown-kanban tool.
Thanks to xet7.
A <summary> line must be on one line - a wrapped one renders its second
line as literal text instead of part of the link. changelogFormat.test.cjs
already checks this; it was failing before this fix.
Thanks to xet7.
test-menu.sh mirrors the docs/Features menu structure and runs the actual
WeKan code for each feature: a dedicated runner for Login (a real REST
username/password round trip) and ImportExport/PDF (create a board, export
it, check the PDF header), and a generic fallback that matches a feature
against this repo's own automated tests by filename. Every feature run
writes output.txt/result.txt/run.log under .tools/test-menu/<timestamp>/,
mirroring the docs/Features path, and never leaves an empty or missing
result.
The example INPUT for a feature is checked into the repository next to its
documentation instead: docs/Features/<path>/example-input.txt, hand-written
for Login and ImportExport/PDF and extracted from the feature's own .md
elsewhere. test-menu.sh only reads these; it never writes into docs/Features.
An earlier version of the matcher also grep'd test file CONTENTS for a
keyword once the filename search failed, which pulled in noise (a word like
"webhook" mentioned in passing in a dozen unrelated tests); it is
filename-only now.
Thanks to xet7.
The menu and its submenus are read live from docs/Features, so they can
never drift from it: a folder is a submenu, a folder with no subfolders of
its own is a runnable leaf, menu 1 always runs every feature, and 0 goes
back/exits. Login and ImportExport/PDF are wired to real WeKan server code -
a REST username/password login round trip and a board create-then-export-PDF
call - reusing an already-running WeKan or starting the precompiled
.build/bundle if one exists. Every other leaf falls back to running this
repo's own matching tests/*.test.cjs, which is a real, working way to
exercise a feature without a dedicated runner.
Each run's starting command, log and any produced files (e.g. the exported
PDF) are saved under .tools/test-menu/YYYY-MM-DD_HH-MM-SS/, mirrored into the
same subfolders as docs/Features.
Restore editable external image URL fields for the login logo, top-left
corner logo, and board backgrounds, and undo the switch to server-side
download-and-convert-to-GIF storage. Uploading is still available as an
option alongside the URL field for boards; instance and Organization
branding again accept a direct image URL. Imports may again carry
Trello's and WeKan's external background URLs. Tests updated to match.
Exclude generated Playwright artifacts from documentation coverage, follow current Finnish translations, keep report fixtures within display limits and provide valid attachment metadata. Require the named HttpOnly login cookie on both transports and Secure on HTTPS.
All 790 Node suites and 15 targeted HTTP/HTTPS browser checks pass.
Thanks to xet7.
The extra resume introduced in 9f47f00cf rebuilds subscriptions after Accounts has already restored the session. Browser DDP diagnostics reproduce an empty profile while the user ID remains logged in and the database profile is unchanged. Transfer the existing credential and expiry to memory, remove the persistent copy and use the native validated cookie endpoint without another login. Keep the token poll in sync.
Extend the regression beyond checking user ID: verify the name, avatar and header color after the poll interval, edit the name and color, favorite the board, change to list view and reload using only the HttpOnly cookie. Chromium and Firefox pass at testi.wekan.fi; unit cases cover completed and pending initial resumes and cookie-only startup.
Thanks to Alishara and xet7 !
Fixes#6677,
Restore independent swimlane control and hover colors and the previous card control styling. Reverse the client changes from fa8c3959c and ebb35af50 and update regression coverage for the restored behavior. Verify the computed colors in Chromium and Firefox at testi.wekan.fi.
Thanks to Alishara and xet7 !
Restore HTTPS transport selection in Playwright readiness checks. Wait for the rendered board denial instead of network silence so SockJS polling cannot time out the non-member test.
Eight live checks pass at https://testi.wekan.fi across Chromium and Firefox, covering standard Meteor sign-in, JavaScript-disabled responses, board loading and non-member denial. The HTTPS readiness regression also passes.
Thanks to xet7 !
Remove the progressive HTML4/Legacy Omi middleware, cookieless sessions, page controllers, assets, parity refactors, design documents and associated tests. Restore the standard Meteor interface and operations from before the HTML4 work began.
Preserve intervening translations, backup screenshots, session upgrades, cryptographic test identifiers, local image storage, document previews and lazy browser loading. Extract the GIF utilities still required by image features into imageGif.
Validate the Node suites and add standard-interface and GIF regressions. Two existing failures remain in docsLinksResolve and ruleDetailsLocalization; browser regressions are registered but require a running server.
Thanks to xet7 !
Capture and resume the pre-upgrade browser token before Accounts.config replaces local storage with its in-memory store. This prevents the existing token poll from logging the user out and discarding reactive profile settings after upgrading from v11.39, while completing migration to the native HttpOnly cookie flow. Add static positive and negative guards plus a browser upgrade regression covering identity and board preferences beyond the poll boundary.
Thanks to Alishara and xet7 !
Fixes#6677,
Record the shared invite-policy boundary, complete accessible Roles controls and capability table, repaired runtime translation feed, Admin Panel navigation coverage, live same-route screenshots, and remaining People and Attachments work.
Share the invite-role policy service between Jade and semantic cookieless HTML4 controls, expose the enforced role capability matrix, and block direct DDP writes. Restore complete Admin Panel navigation and separate exact-language runtime translations from the bounded admin search publication.
Record the completed seven-pane Settings coverage, the shared translation security and accessibility contract, live same-route verification, and the modern 25-row counter correction in the upcoming release notes.
Share bounded admin translation services between the modern and HTML4 views, keep literal search selectors server-owned, block and report direct DDP writes, and provide complete semantic create, edit, search, paging and confirmed-delete controls. Verify both views on the same live route and keep their 25-row counters aligned.
Expose explicit parent text and a two-step signed Reply form with unique labels in cookieless HTML4. Reuse the bounded common comment service, reject foreign parents, preserve activity history, and compare the same threaded card in both renderers.
Share bounded, card-scoped comment creation, editing and deletion between Meteor and cookieless HTML4. Enforce assigned-board and author/admin policy, report boundary probes, preserve activity history, and require a signed two-step delete confirmation.
Add a shared labelled select component and an authoritative card placement operation used by Meteor and cookieless HTML4. Reject foreign or archived destinations, compute ordering server-side, and verify list movement and refusal at the same card URL.
Share authorized title, description, archive and restore operations between Meteor and signed cookieless HTML4 forms. Validate linked targets and descendant trees before writes, report refused cross-board attempts with actor details, and verify both views at the same card URL.
Share authorized card creation and deterministic up/down ordering between Meteor and signed cookieless HTML4 forms. Keep controls labelled and keyboard ordered, reject forged cross-board placement, and cover both representations with same-route browser screenshots.
Read whole-board and scoped archives through one bounded path-safe service, stream attachment bytes through the standard Default Storage hook, and preserve stable attachment ids in ZIP exports. Add the signed HTML4 ZIP upload, fix Meteor-Files 3 Promise handling, and verify valid and traversing archives in a cookieless browser.
Expose a separate signed ZIP upload form and reuse the existing guarded Trello package importer after cookieless session validation. Preserve request attribution, enforce the global import switch on both HTML4 and HTTP Trello imports, and verify a real archive creates a board.
Stream bounded multipart uploads into private temporary files, validate the signed cookieless form before importing, and remove every temporary file after use. Reuse the normal sanitized board importer for both JSON and Excel uploads and cover both formats with browser tests.
Provide the shared textarea component and use it for bounded JSON and CSV imports without JavaScript or cookies. Execute the existing authenticated, sanitized, deadline-bound importBoard method, retain safe correction feedback, and link the successfully created board. Cover malformed JSON and a complete CSV import in Chromium.
Render every shared board export field as a semantic import toggle. Carry the validated selection through one-use signed POST forms, preserve an explicit empty selection, ignore forged fields, and verify the controls against the HTML5 Trello import view.
Move the ordered import formats into one registry consumed by both renderers. Give cookieless clients a signed, keyboard-accessible source picker at the existing import URLs, retain branded WeKan naming, and compare the Trello picker in same-URL screenshots.
Apply the shared Starred, Remaining, Home, Templates, Archive, and nested Workspace selection rules to cookieless All Boards routes. Render every section and workspace as a signed POST control, preserve board visibility boundaries, and compare the Templates route in both renderers.
Show checklist items, sanitized attachment metadata, and comments in the semantic card table after the parent card passes the board and assigned-only authorization scopes. Keep every child query tied to both the card and board identifiers, and cover successful rendering plus cross-board non-disclosure in the browser test.
Render the opened card's path, description, labels, people, archive state, and dates at its existing URL. Repeat board visibility and assigned-only card scopes before reading child identities, add complete translated navigation labels, and compare the same card in JavaScript and no-JavaScript Playwright contexts.\n\nThanks to xet7 !
Document the authenticated readers, signed search form, authorization boundaries, remaining advanced-query work, and no-JavaScript browser coverage.\n\nThanks to xet7 !
Render My Cards, Due Cards, Bookmarks, and basic Global Search through authenticated server-side controllers. Scope cards to the user's boards, preserve membership filters, add a labelled signed search form, and keep bookmark URLs sanitized by the shared model. Test cookieless navigation, search, due dates, bookmarks, and private-board exclusion in a real no-JavaScript browser.\n\nThanks to xet7 !
Render Accessibility, Support, and Keyboard Shortcuts from their existing settings and translation data. Share shortcut mappings between Jade and HTML4, preserve authorization boundaries, document why the complete baseline is not confined to noscript, and track controller coverage. Add source and same-URL Playwright regression tests.\n\nThanks to xet7 !
Document the shared semantic component registry, browser compatibility baseline, live comparison, cached GIF repair, and regression coverage.\n\nThanks to xet7 !
Define common semantic controls with printable ASCII fallbacks, document the IBrowse, NetSurf and Dillo baseline, expose matching component galleries, and use the registry for swimlane and server-rendered controls. Preserve accessible table structure and board colors, and repair missing cached login-logo GIF files on demand. Add regression coverage for the shared routes, icons, markup and keyboard order.\n\nThanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Render the sign-in page from the same product, logo, legal-notice, account-option and translation settings as the HTML5 view. Convert the configured or built-in login logo to a server-side GIF system asset and persist it in Default Storage.
Remove the former prototype name from WeKan code, routes, stored GIF version metadata, tests, build comments and documentation. Explain on the sign-in page that the Legacy HTML4 view is active because JavaScript drag and drop is unavailable.
Resolve Sharp through Node only when an authorized Omi image request needs conversion. A missing or incorrectly bundled native addon can no longer crash WeKan or replace the HTML4 sign-in page with Meteor's application error.
Serve an HTML 4.01 baseline at every WeKan page URL and upgrade to the Meteor client only after behavioral JavaScript and drag-and-drop capability checks pass. Convert Omi attachment images to stored GIF versions on the server using the configured default attachment storage.
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Add a read-only release consistency gate after version.sh and before the workflow commits its bump. Reject stale package, lockfile, Docker, Snap, Stacker, Sandstorm, bundle URL, or Meteor metadata versions with explicit errors and regression coverage.
Thanks to xet7 !
Generate website version information from .meteor/release instead of stale Docker metadata, and synchronize that metadata during every release bump. Cover a prerelease mismatch where Docker says beta but the actual Meteor build pin says rc.
Thanks to xet7 !
Resolve the Unix checkout relative to the release script so both documented Linux and macOS locations work, and add a Windows batch version for the Downloads checkout. Ensure existing mirrors are updated on repeat runs and add non-network regression coverage for paths and commands.
Thanks to xet7 !
Center the minicard drag glyph directly beneath its menu without a scaled offset. Use the same compact swimlane handle markup and position on touch and mouse devices, and cover both computed positions in the live browser suite.
Thanks to xet7 !
Do not inject board list names into the quick-access bar when a list opens in Mobile Mode. Keep list navigation in the swimlane rows and verify the header text and height remain unchanged in the live browser test.
Thanks to xet7 !
Scope the mobile list-header selected state to the list whose ID is selected, so compact rows in other swimlanes retain the same controls and height. Extend source and live browser coverage to compare untouched row heights before and after opening another swimlane's list.
Thanks to xet7 !
Escape backslashes before quotes in OOXML CSS font families, and replace four backtracking language-registry regexes with a linear parser.\n\nThanks to GitHub CodeQL and xet7 !
Put the Admin Panel email-provider option at the top of email troubleshooting and clarify its opt-in relationship with MAIL_URL across related documentation.\n\nThanks to xet7 !
Keep direct minicard title editing commented out. Without drag handles, the title moves the card; with handles, it remains available for board drag-scrolling.\n\nThanks to xet7 !
The activity strings and the comment/organisation settings, using the
vocabulary sq already established - Tabelë, Kartë, Listë, Korsi, Listë
kontrolli, Etiketa, Bashkëngjitje - so the file stays consistent with the 148
strings that were there.
Every placeholder is copied from the English source unchanged, including the
capital L in __checkList__ that one activity string uses; the file has no
placeholder mismatches.
Albanian: 2176 untranslated to 2116.
Thanks to xet7 !
Records this batch: the attachment-serving bypass as a SECURITY ISSUE at the
top of the release, the four portability and test fixes under the build-tree
group, and Bosnian under a new translations subsection.
Thanks to xet7 !
A Playwright spec found this, and it found more than it was asking about.
"stored HTML is forced to a safe download on the original Meteor-Files route"
expected application/octet-stream and got text/html, status 200 - a stored HTML
attachment served inline, which is the stored XSS that
models/lib/fileResponseSafety.js exists to prevent.
That policy module is correct. It was never reached. Meteor-Files calls the
storage strategy's interceptDownload, and a FALSE return means "not handled,
serve it yourself" - so Meteor-Files served the file from its stored path, with
its stored Content-Type, and none of WeKan's headers.
What makes that a bypass rather than a harmless fallback is WHY the strategy
declines. getReadStream() returns nothing when the file cannot be resolved
INSIDE the storage root, which is the containment check of
GHSA-4mxf-m8pq-xc9p. So `false` means "this is not a file WeKan may serve", and
handing that same file to a server with no containment check of its own answers
the refusal with the file. The safest possible verdict and the most dangerous
outcome, from one boolean.
All three strategies answer 404 and claim the request now. So does the abstract
base, whose body was EMPTY - returning undefined, which Meteor-Files reads
exactly as it reads false, so a strategy that forgot to override it failed open
too. A strategy that forgets should serve nothing rather than serve it
unfiltered.
A file that is genuinely absent gets the same 404 it would have got anyway.
Not logged to Admin Panel / Problems, and that is a decision rather than an
omission: the same path is taken by an attachment deleted while a link to it
survived, which is ordinary use, and interceptDownload cannot tell the two
apart - getReadStream() reports only that it has nothing. Telling "outside the
root" from "not there" is what a key would need first.
The spec had also been writing its file to the wrong place. build.sh exports
WEKAN_FILES_PATH_HOST, which is the path mounted into the browser CONTAINER, so
a local run fell back to the spec's own default of .build/bundle/files while the
server read .tools/test-writable/files. It exports WEKAN_FILES_PATH too now, so
the spec exercises a file the server owns - which is what it meant to test, and
without which it was measuring the bypass instead.
tests/attachmentServeFailsClosed.test.cjs pins that NO interceptDownload
anywhere returns false, that each refuses with a 404, that every serving
strategy still goes through the single policy choke point, and that text/html
is still forced to a download by type and by filename - with an ordinary image
still served inline as the negative.
Thanks to xet7 !
FileStoreStrategyFilesystem builds its candidate paths by joining names onto
the storage root AS WRITTEN, then checked each one against that root with every
symlink RESOLVED. Those are the same string only when nothing in the path is a
symlink.
On macOS nothing is: os.tmpdir() is /var/folders/..., a symlink to
/private/var/folders/..., so every candidate failed containment before it was
looked at and getReadStream() returned undefined - WeKan serving none of its
own attachments. A deployment whose data directory is a symlink, which is an
ordinary arrangement, has the same fault on Linux. The mocha suite has been
reporting it all along as "allows reading a regular file from storage root",
which reads like a fussy assertion rather than like a platform that cannot open
attachments.
The lexical pre-filter now uses the root the candidates were built from. The
security property is untouched, because it was never that check which carried
it: what a caller must not do is reach a file OUTSIDE the root, and that is
decided by resolving the candidate and requiring the result to be inside the
resolved root. GHSA-4mxf-m8pq-xc9p's symlink escape and the plain absolute-path
escape are both still refused, and tests/fileStoreSymlinkRoot.test.cjs pins
that against a real symlinked root - including the exact comparison that caused
the bug.
Bosnian: 2175 untranslated strings to 1. Croatian and Serbian are complete and
Bosnian is the same Stokavian standard, so Croatian is the base, with the
documented Bosnian forms applied - sedmica for tjedan, nivo for razina, server
for posluzitelj, tok for tijek, hiljada for tisuca, historija for povijest, and
tacka/tacno for tocka/tocno. 29 strings needed one; the rest are identical in
both standards.
Two substitutions were REVERTED after reading the output, and that is the part
worth keeping: `poveznica` to `link` produced "iz ove linkove" and "iz bilo koje
linkove na kartu", because `poveznice` is both nominative plural and genitive
singular and one rule cannot be both. `poveznica` is good Bosnian, so it stays -
a correct word left alone beats a more idiomatic one put in the wrong case. The
same blindness left "Najviša nivo", feminine adjective on a masculine noun,
which is fixed by matching the whole phrase.
The last ten were translated directly. The one that remains is "Server", which
is spelled that way in Bosnian too - the tool counts a translation identical to
its source as missing, and that is the tool's limit, not a gap.
Thanks to xet7 !
bundleSmokeBoot. releases/bundle-smoke-boot.sh runs the bundle under `timeout`,
which is GNU coreutils and is not on macOS. It died with "timeout: command not
found" and exit 127 - which the script's own checks then read as "the bundle
exited without reaching its database", reporting a startup failure for a
missing utility. It now uses timeout, or gtimeout, or a shell fallback that
backgrounds the command and kills it, which needs nothing but the shell.
fixedVulnerabilityClasses. The Hall of Fame comparison demanded at least 50
*bleed directories in the wekan.fi checkout as a "is this the right directory?"
sanity check. That number is a count of what was published when the line was
written, so a checkout two months old has fewer and the suite went red over the
state of ANOTHER repository, which no change here can fix.
A stale checkout cannot cause a false failure there: the test asks, of each
vulnerability it lists, whether some test names it, so listing fewer makes the
check smaller and never wrong. What the threshold has to catch is a directory
that is not the Hall of Fame at all, and those have none - so that is what it
asks now. It also looks in .tools/wekan.fi first, which is where CLAUDE.md puts
the website companion, before the older paths beside the repo.
The check itself passes: all 31 vulnerabilities in that checkout are named by a
test.
The node suites are now 721 run, 0 failed.
Thanks to xet7 !
These had been failing on every run, and each turned out to be a different
fault rather than a broken assertion.
autopickReadLeavesNoTrace. snap-src/bin/database-autopick reads MongoDB's
data-file mtimes so that starting mongod to compare the two databases does not
make MongoDB look freshly written. It spelled that with `stat -c %Y` and
`touch -d @EPOCH`, which are GNU. On macOS the stat fails, every file is
skipped by the `|| continue` beside it, MONGO_MTIME_BEFORE stays 0, and the
restore returns having done nothing - silently, and only there. The snap runs
on Linux, but WeKan is developed on macOS and this test runs the real functions
wherever it is run. They now try the GNU spelling and fall back to the BSD one.
provenanceTable. releases/provenance-table.sh opened with
`shopt -s nullglob globstar`, and globstar arrived in bash 4 while macOS still
ships bash 3.2 as /bin/bash: "shopt: globstar: invalid shell option name", and
`set -e` took the script with it. The default file list is a single `find` now,
recursive as `**/` was, with -print0 so a path containing a space survives.
Then the empty case failed too - under `set -u`, bash 3.2 calls an empty array
an unbound variable where 4.4 does not - so the loop uses the
`${files[@]+"${files[@]}"}` form.
sesothoTranslationProgress. Two faults. The script's own `--list` output was
TRUNCATED whenever stdout was a pipe: it prints 128 KB with console.log and
then calls process.exit, which cuts off whatever has not drained, and a pipe
delivered 65,510 bytes - valid-looking JSON stopping mid-key, with status 0.
Redirecting to a file worked, because stdout to a file is synchronous, so this
only bit anything that read the output programmatically. It is written with
fs.writeSync in a loop now, EAGAIN retried, before the exit. The test's other
half asserted an EXACT count of untranslated strings, which went red when
ENGLISH gained the four history-change-* keys - a fact about English, not about
Sesotho. It is a ceiling now: still catches a translation being lost, and does
not demand editing for every new string.
Two of the three guards were updated rather than the code, and both times
because they pinned a spelling rather than a behaviour - the exact globstar
pattern, and an exact count. Both now assert the property that was wanted.
A note for the next one: two of these assertions had to be re-scoped to the
CODE because they matched the COMMENT explaining them. Prose satisfying an
assertion about code is how a guard passes while testing nothing.
Thanks to xet7 !
Records the open-file limit fix: mongod started with 256 descriptors, warned
about it, and aborted thirteen minutes into a Playwright run - after which
every spec reported ECONNREFUSED as if the database had never started.
Thanks to xet7 !
A full Playwright run died thirteen minutes in and every spec after it
reported the same thing:
MongoServerSelectionError: connect ECONNREFUSED 127.0.0.1:3001
which reads like the test database was never started. It was: it started at
03:03:03, said what was wrong with it in the same breath, and was ignored.
"Soft rlimits for open file descriptors too low"
currentValue: 256, recommendedMinimum: 64000
Thirteen minutes later it ran out:
Error accepting new connection ... "Too many open files"
__directory_list_worker ... journal: directory-list: opendir
WT_PANIC: WiredTiger library panic ... the process must exit and restart
build.sh: line 1148: 22176 Abort trap: 6 mongod --port 3001 ...
macOS starts a shell with a soft limit of 256 open files. build.sh never
raised it, so every run of the browser suites was a race between finishing and
running out of descriptors - and the failure lands 10,000 lines away in another
log, in a form that points at the wrong thing entirely.
ensure_open_files sits beside ensure_inotify_watches and runs on every
invocation, for the same reason: a limit that is too low breaks a later step
with an error that does not name it. Unlike that one it needs no root - the
hard limit is normally unlimited, so the process raises its own soft limit and
mongod, the bundle server and the browsers inherit it.
Two details, both found by running it rather than reading it:
It sets the SOFT limit explicitly. Plain `ulimit -n` sets soft and hard, and
lowering a hard limit is irreversible for the process - the first version
lowered its own ceiling and could then raise nothing.
It clamps to the hard limit and steps down from there. Asking for more than
the hard limit fails outright rather than clamping, and macOS also caps a
process at kern.maxfilesperproc, which the hard limit does not always
reflect.
tests/buildScriptOpenFiles.test.cjs runs the function in shells with 256,
70000, and a 5000 hard limit, checks the opt-out, and pins both details above.
Thanks to xet7 !
Audited the section against git rather than against memory: every commit since
v11.49 is compared with the hashes linked here, and three had no entry.
f72f361bb the per-OS checkout paths - and, said plainly, that this same
commit claimed all commits go on main, which the entry below it
corrects in this same release
77dd5f253 what opening History actually proved, and what it did not
9b28c793f the commit links repointed after a rebase made them stale
The only commits now without an entry are the "Update upcoming WeKan
changelog" ones themselves, which is how every earlier release reads.
The In short paragraph was describing the release as it stood several commits
ago - it opened on copying a list and did not mention the History panel or
Restore at all. It now leads with what the release is actually about and stays
inside the 120-word cap the format test enforces.
No new regression coverage was needed: the three entries added are
documentation commits with no behaviour of their own, and every behavioural
entry in the section already carries its tests.
Thanks to xet7 !
Records the restore fix: the table shows a row's new content and Restore
applied its previous one, so picking a version gave you the one before it.
Thanks to xet7 !
Reported as "when I try to restore card description from card history, it
restores wrong history, that I did not select" - and the selection was never
wrong. The server restored exactly the row whose checkbox was ticked. It
applied the wrong half of it.
A row carries two contents, before and after. The History table shows the
AFTER - History.md 7 says the content column holds "the new text" - and
Restore applied the BEFORE, because it reused the undo path: `applyRow(row,
'undo')`. So choosing the row that displayed the description you wanted handed
you the description from the row above it, and choosing rows one after another
walked backwards through the history instead of moving through it.
Restore now has a direction of its own. The rule is one sentence: the row a
reader picks and the value they get are the same thing. A row with no new
content is a removal, so restoring one puts back what it removed.
Undo is deliberately the other way round - Ctrl+Z reverses your own last
change - and is unchanged. The two only agree when the row you pick happens to
be the last one, which is why this survived the first pass: the live check
restored a title that WAS the most recent change, so undo and restore gave the
same answer.
The rule moved into `contentForDirection` in models/lib/changeHistoryGroups.js
so it can be tested as arithmetic, with no server and no database, and so
applyRow and the restore method cannot drift apart.
A restore is itself recorded, and those rows were wrong in the same way: they
repeated the restored row's own before/after, which describes a different
change. The live value is now read BEFORE the write and recorded as what was
displaced, so restoring FIRST over THIRD says so.
Verified against a running server: three description versions, FIRST, SECOND,
THIRD, with THIRD current. Picking the row showing FIRST set the description
to FIRST and logged THIRD -> FIRST; then picking SECOND set it to SECOND and
logged FIRST -> SECOND. Before this, picking FIRST emptied the description.
tests/historyRestoreAppliesWhatIsShown.test.cjs pins the rule from both ends -
what restore applies, and that the table shows that same content - along with
removals, additions and junk input. tests/changeHistoryWiring.test.cjs pinned
the old inline ternary by its text; it now runs the rule instead, which a move
like this cannot break.
Thanks to xet7 !
Records the two faults inside the History panel: the collapsed stack entries
that grew when the container became a flex column, and the table whose
`width: 100%` produced a scrollbar with nothing to scroll at wide widths and
an unreachable overflow at narrow ones.
Thanks to xet7 !
Both faults were inside the panel, which is why measuring its frame found
neither: the gaps around it were right the whole time.
THE EMPTY BAND ABOVE THE SEARCH BOX. `.content-container` holds the whole
popup STACK - one `.content` per entry, with the ones you are not looking at
collapsed by `.content.no-height { height: 0 }`. Making the container a flex
column turned those into flex items, and the growth rule applied to all of
them: `flex: 1 1 auto` says grow, and `height: 0` is only the basis it grows
from. So the card menu History was opened over stayed in the layout and took
336px of a 925px window. Only the entry being looked at grows now, and the
collapsed ones are pinned to `flex: 0 0 0 !important` - important because the
rule it has to beat, `.pop-over .content { flex: 1 1 auto !important }`,
carries one.
THE SCROLLBAR WITH NOTHING TO SCROLL. `width: 100%` on the table was wrong at
both ends, in opposite directions. Wide: WeKan's global `table, td, th` rule
gives the table a `border-inline-start: 1px` - those are the vertical lines
between the columns - and this file's reset makes `*` content-box, so 100%
sized the CONTENT and that border was added outside it. Columns summing to
993.047 in 993.047 of space, border box 994.047: one pixel of nothing, drawing
a bar across the foot of the panel at every width the table actually fitted.
Narrow: the table stayed at 100% while its columns needed 436px, so they
spilled OUT of it, and the scroll box measures the table rather than its
spill - the columns were unreachable, with a 1px scrollbar suggesting
otherwise. `width: max-content` sizes the table to what the columns want,
`min-width: 100%` keeps it filling the panel when they want less, and
`box-sizing: border-box` puts that 1px inside the 100%.
Two wrong turns are recorded in the comments because both looked right:
`border-collapse: separate` on the theory the 1px was a collapsed border (it
is not - the border is set explicitly by that global rule and survives), and
`box-sizing` alone, which removes the pixel by pinning the table to 100% and
so converts a real overflow into a hidden clip.
The gutter stays DESKTOP-ONLY. It was briefly made unconditional and that is
wrong: below 801px, and in mobile mode at any width, a popup is a full-screen
sheet flush to all four edges, and it should stay that way. The height chain
above it is NOT in a media query, for the opposite reason - the sheet still
has to pass its height down or the scrollbar ends up halfway up the panel. The
test now pins both directions, since they pull against each other.
Measured, desktop mode at 886x711: 10px on all four sides, no horizontal
scrollbar, 65px above the search box - the panel header and nothing else. At
375x812: edge to edge, and a horizontal scrollbar with 169px of real scrolling
instead of one pixel of none.
Thanks to xet7 !
Records the small-width half of the panel fix: the height chain that was
written desktop-only, the percentage heights that had no definite parent on a
full-screen sheet, and the two caps that ate the edges.
Thanks to xet7 !
Above 801px the panel already ended the same 10px from the bottom that it
starts from the top. Below that, where popup.css lays every popup out as a
full-screen sheet, it did not: the horizontal scrollbar sat halfway up the
panel with blank space beneath it, because nothing carried the sheet's height
down to the rows.
Measured at 375x812, three separate things were wrong, and all three were
percentage heights or caps that a diff cannot show:
THE CHAIN WAS DESKTOP-ONLY. The rules passing the height from the pop-over
shell to the template were written inside `@media (min-width: 801px)` - which
is exactly backwards, since above that width the panel is given a height
directly and below it the sheet is the only thing that needs help. Moved out,
and pinned there by a test that matches braces rather than looking for a
closing line: an earlier version of that guard searched for the next `\n}`
and a rule inside the block satisfied it, so it passed while the chain sat in
the media query it is meant to stay out of.
PERCENTAGES HAD NOTHING TO RESOLVE AGAINST. `.content-container` stopped at
588px - `max-height: calc(70vh + 20px)` from the base rule, whose
`.pop-over--bounded` override does not apply to a sheet because that class
comes from an inline max-height popupOffset.js does not send one of - and
`.content` collapsed to 10px, its `height: calc(100% - 20px)` resolving to the
padding alone. The chain is flex now, the whole way down: a flex item that may
grow and shrink needs no parent height, and `min-height: 0` is what lets it
shrink rather than being stretched by its own content.
AND TWO CAPS ATE THE EDGES. `.pop-over { max-height: 90vh !important }` left a
tenth of the screen empty under the sheet - 731px of 812. The mobile block
already tries to undo that and loses, having the same specificity and being
written earlier, so the override here carries the attribute selector and wins
on specificity instead. And this file's reset makes `*` content-box while
`.pop-over` has a 1px border, so the stated `calc(100vh - 20px)` drew 2px
taller than it says: 10px above against 8px below, at any width where
`.pop-over--bounded` happened not to be applied.
Verified in a browser at four sizes - 375x812, 768x1024, 886x711, 1280x720.
Under 801px the sheet fills the screen, as a sheet should; above it the gaps
are 10px on all four sides; and in every one of them the horizontal scrollbar
is at the foot of the panel.
The guard now strips CSS comments before matching declarations. It had started
passing on the comment that QUOTES `height: calc(100vh - 20px)` while
explaining it - prose satisfying an assertion about code.
Thanks to xet7 !
Records the panel's geometry fix under the History group: the height, the
anchor margin that does not belong on a pinned panel, and the fixed
positioning a box sized from the viewport needs.
Thanks to xet7 !
The panel was pinned 10px below the top of the window and then stopped
wherever its contents ended: a two-row table sat in the top eighth of the
screen with the rest of it blank. It now ends 10px above the bottom, so the
space a reader sees under it is the space they see over it - measured at
1280x720: 10px on all four sides, a 700px panel, unchanged in RTL.
Three separate rules were needed and each was found by measuring rather than
by reading:
A HEIGHT. popupOffset.js already sent a max-height of the right size, and a
maximum alone lets a short table stay short. Stating `height: calc(100vh -
20px)` is what fills the window.
NO MARGIN. The base .pop-over adds `margin-top: 6px` - the little gap between
a menu and the button that opened it. These panels are not hung off a button;
popupOffset.js pins them to the viewport's 10px gutter, so the margin was
added to a position that was already final. Every full-width panel sat 16px
from the top while its own comment said 10, and on History, which now has a
stated height, it also pushed 6px past the bottom: 16px above against 4px
below. Zeroed for the export panels too, which have the same contract.
FIXED POSITIONING. Every other popup is absolute in DOCUMENT coordinates,
which is right for a menu that should travel with its button and wrong for a
box sized from the viewport. Opened on a page scrolled 53px down and then
scrolled back, the panel stayed at document y=63 - 63px below the window with
43px of itself past the bottom. It is positioned from the viewport now, like
the Admin edit popups above it, which solve the same problem the same way.
The height then had to reach the table, or the blank space would only have
moved indoors: the three wrappers between the pop-over shell and the template
pass it down, .history-main is a column so the rows take what the controls
leave, and .history-scroll grows instead of being capped at 55vh. With 40 rows
the panel stays 700px and the rows scroll inside it.
The offsets are logical rather than `left`, because tests/rtl.test.js rejects
physical ones - and both ends are named, since the template writes an inline
`left:` that a start-only rule would leave in force in RTL.
tests/historyOneTemplate.test.cjs pins all three rules and that the height
reaches the rows. The height assertion excludes `max-height` explicitly: it
matched a loose pattern and passed while testing nothing, which is the exact
state this commit fixes.
Thanks to xet7 !
The previous commit verified the card scope. The rest has now been opened too,
so the document and the changelog say what was done rather than what was
likely: the card, list and swimlane menus each open the table with their own
scope reaching the template; search narrows it and reports no results for a
term nothing matches; a contributor's avatar filters to that person; and with
32 rows the footer reads 1 / 2, the second page holds the remaining seven in
sequence, and the next arrow disables itself there.
Nothing new was found. That is worth recording as plainly as the four faults
the first pass found, because "it shares a template with something that works"
is the reasoning those four faults survived.
Thanks to xet7 !
Records what opening History found, and corrects History.md, which still said
none of it had been exercised in a running WeKan. The card scope now has been:
what was verified, what the pass found, and - said plainly, because it is the
same reasoning that produced those four faults - which scopes remain untested.
Thanks to xet7 !
The change history and its table were written without a Meteor runtime
available, and both documents said so. Opening it found four things that no
amount of reading the source would have shown, three of which made the
feature useless.
THE TABLE WAS BLANK. `{{#each row in rows}}` binds `row` as a NAME and leaves
the data context alone - unlike `{{#each rows}}`, which replaces it - so
`{{_id}}`, `{{contentSummary}}` and the rest resolved against the OUTER
context and rendered nothing. Nothing errors: the table drew one row of four
empty cells and a checkbox with no id. Same bug in the contributor loop. Every
field now goes through its loop variable.
THE ROW COULD NOT BE SELECTED. WeKan hides every bare checkbox app-wide -
forms.css: `[type="checkbox"] { display: none }` - and draws `.materialCheckBox`
divs instead, so the real one here rendered 0x0. The row was visible, could
never be ticked, and Restore stayed disabled with nothing that could enable
it. It is now the control the rest of the app uses, clicked rather than
changed, drawn from the selection state.
THE PANEL WAS 380px WIDE. A popup's default width left 129px for the
contributor pane and 201px for a four-column table; the search box was
squeezed to 32px and one row had to be scrolled sideways to be read. History
is the same shape as the export panels - two panes, opened from a menu at the
edge of the screen - so it joins them in popup.css and in the FULL_WIDTH_POPUPS
list in popupOffset.js, which is the other half that decides where a panel is
placed. The rows also scroll in a wrapper now rather than in the table itself:
`display: block` on a <table> stops the cells sharing column widths, so the
header and the rows beneath it drift apart.
AND A RESTORE WAS RECORDED TWICE. This one is a correct decision with a
consequence: History.md 8.2 says a restore re-applies content through the
SAME setters an ordinary edit uses, so validation, hooks and Activities all
still run. The field-diffing after.update hook is one of those hooks, so it
saw the restore's own write and recorded it - and restoring a title left an
`edited` row nobody made sitting above the `restored` row describing the same
write. Recording, and only recording, is now switched off for the duration of
the applier.
That switch is an AsyncLocalStorage scope, not a module-level boolean, and the
difference is not stylistic: the server handles several requests at once, and
a shared flag set during one user's restore would have silently swallowed
another user's edit landing in the same window - a data-loss bug that appears
only under concurrency and would never be seen in testing.
Verified against a running server rather than by reading: a card renamed
through the UI recorded one row with the right group, previous and new value;
History showed it; selecting it and pressing Restore put the title back and
left exactly two rows, the edit and the restore.
tests/historyOneTemplate.test.cjs pins the loop-variable rule, the checkbox
control, the panel width in both files that decide it, and the scroll wrapper.
tests/historyRestoreRecordsOnce.test.cjs pins the suppression, that a restore
still writes through the normal setters, and - running two overlapping async
operations for real - that a concurrent edit by another user is still
recorded.
Thanks to xet7 !
Records the three commits that had no entry yet - the moment import that
broke the client build, the ignore files being brought to one answer about
what is not source, and the corrected note about what ignoring .build does.
Also puts the release's subsections in the order the house style asks for.
The Undo and History work sat under "and states the rules a contribution is
judged by", which was written for the Contributing group below it; the
feature now has its own "This release adds the following new features:"
header, the swimlane fixes follow as bugs, and the tooling fixes close.
Thanks to xet7 !
The comment beside /.build/ in .meteorignore said the entry was Meteor's
"The output directory is under your source tree" warning "answered". It is
not, and the warning printed on the very next build says so.
That warning is a path comparison on the output ARGUMENT, made before any
file is written: tools/cli/commands.js asks whether
pathRelative(appDir, outputPath) starts with '..' and prints it when it does
not. No ignore file is consulted and none can reach it. Silencing it means
building outside the tree, which build.sh, build.bat and the release
workflows would all have to agree on.
What the entry does is the second half of the same warning - "may get
interpreted as source code". Without it the next `meteor run` walks a whole
bundled copy of the app, so it is worth having on its own merits, which is
what the comment now says.
tests/meteorignoreScanScope.test.cjs pins both directions, one character
apart: _build must NOT be ignored (it is the handoff Meteor reads its
mainModule from) and .build must be, and the false claim cannot come back.
Thanks to xet7 !
Two build directories exist and their names are one character apart, which is
how one of them got scanned as source by a test earlier today:
.build/ the RELEASE bundle, from `meteor build .build --directory`.
.build/bundle is what is deployed, tested and packaged.
_build/ rspack's compiled output, written by ANY Meteor compile. Meteor reads
the app's main modules from _build/main-prod/, so it is a HANDOFF,
not a leftover - which is why .meteorignore must NOT ignore it, as
the note in that file has said since the Meteor 3.4 migration.
Both are now described where somebody meets them: the build.sh and build.bat
headers, Directory-Structure.md, Build-from-source.md, Meteor-bundle.md,
Build-and-Create-Pull-Request.md (as "what not to add to a pull request"), and
CLAUDE.md/AGENTS.md - the last with the warning that _build holds a bundled
second copy of every source file, so anything walking the repository must skip
it. That is not hypothetical; a source-scanning test read it and reported the
bundler's rewritten imports as a source file breaking a rule.
_build was in .gitignore and .meteorignore only. It is now in .dockerignore,
.eslintignore and .prettierignore too.
The same pass aligned the rest. Nothing in client/, server/, models/, imports/,
config/ or packages/ imports anything from docs/, meta/, old-CHANGELOG/,
openapi/, sandstorm-src/, snap-src/, snap-base-debian/, stacksmith/, releases/,
scripts/, tools/ or secrets/ - checked, not assumed - so Meteor no longer
watches them. It watches what it does not ignore, one inotify watch per
directory, against a per-user limit shared with every other watcher on the
machine: the same limit .tools/ was added for. The Docker context no longer
carries them either, since everything in it is sent to the daemon whether the
image uses it or not.
Four things are deliberately NOT ignored, each for a reason now written down:
config/ is imported by the app in nine places; private/ and public/ are Meteor's
own asset directories; packages/ holds the local Meteor packages; and _build/
breaks the build if ignored. releases/ stays in the Docker context because the
Dockerfile COPYs several scripts out of it.
.meteorignore now also ignores .build/, which answers a warning Meteor prints on
every release build - "The output directory is under your source tree. Your
generated files may get interpreted as source code!" Unlike _build/, nothing
hands .build/ back to the compiler; it is finished output read by the deploy and
test steps.
Thanks to xet7 !
The client build failed outright:
ERROR in ./client/components/history/historyTable.js
× Module not found: Can't resolve 'moment'
moment was removed from WeKan and replaced with native Date functions -
imports/i18n/moment.js says exactly that - so it is not a dependency and nothing
resolves it. The History table now uses formatDateTime from
/imports/lib/dateUtils, which is what the rest of the app uses.
`import moment from 'moment'` is the most ordinary-looking line in a JavaScript
file, and reading the diff would never have shown it, because what was wrong was
somewhere else entirely: the dependency list. So the guard is worth more than
the fix. tests/importsResolve.test.cjs asks the question the bundler asks - can
this specifier resolve, against the real node_modules - across client, models,
imports and server. It finds this class in under a second where `meteor build`
takes two minutes, which is the difference between noticing while writing a file
and noticing after handing the work over.
It also pins the two packages the app imports directly without declaring,
body-parser and mime-types. Those resolve today only because something else
pulls them in, and would vanish if that dependency changed; the list is pinned so
it cannot quietly grow, not because it is fine.
Two more things the build turned up, both about scanning generated files:
tests/undoRecordsWhatItClaims.test.cjs walked into _build/, the bundled copy of
the whole app, and reported the bundler's own rewritten imports as a source file
breaking the import rule. Build output is skipped now.
And the failure count this suite reports has been wrong all along, in the
other direction: 18 "pre-existing failures" were mostly modules that were simply
not installed in this checkout. With dependencies present the suite runs 718
suites with 5 failures, and those 5 are real environment limits - no Docker, no
bundle to boot, macOS bash without globstar.
Thanks to xet7 !
Phases 3, 5 and 6 of docs/Features/Reports/History/History.md, and the viewer of
phase 2.
RECORDING EVERYTHING, FROM ONE PLACE. §5 suggests "a thin, central choke point
... avoids sprinkling calls everywhere", and server/models/changeHistoryHooks.js
is that: an after.update hook per collection that diffs the changed fields, plus
insert/remove for the sub-entities. Cards, lists, swimlanes, checklists,
checklist items and comments are covered across every group §3 names.
The advantage over editing twenty setters is not brevity, it is COVERAGE: the
REST API, the CSV and Trello importers and the rules engine all write through
the collection and none of them call the client setters, so a per-setter rollout
would have recorded a description edited in the UI and silently missed the same
edit made over the API.
What a hook must not do is record too much, so models/lib/changeHistoryGroups.js
is a table rather than a rule: modifiedAt and dateLastActivity change on nearly
every write and would bury the changes a person actually made, and the four
fields of a move only mean anything together - reported separately, one drag
becomes four rows and undo puts back a quarter of it. Card.move and the list
soft delete therefore record themselves, as one change each. The description
setter records nothing now: the hook covers it, and recording in both places
would have needed two presses of Ctrl+Z to undo one edit.
ONE TABLE, EVERY SCOPE. §7a: "there is ONE implementation, parametrised by
scope". client/components/history/historyTable is that one - contributor pane,
search, pagination, row selection, Restore, RTL - and the card, list and
swimlane menus each open it with a different scope. Adding History to a menu is
a menu item and a two-line handler, exactly as the design promises.
tests/historyOneTemplate.test.cjs keeps it that way. Six copies of a table
drift: one gets RTL and the others do not, one gets the search fixed and the
others keep the bug. The test walks every .jade under client/ and fails if a
second History table is ever defined.
Two things the UI needed that were nearly wrong. The scope has to travel as
`dataContextIfCurrentDataIsUndefined`, because Popup.open's second argument is
OPTIONS - a bare object there is ignored and the popup opens on the menu's own
data context, showing the wrong history. And the popup needs a title key or it
renders with no header and no close button; it reuses the existing `history`
key rather than adding one.
FOUR NEW WORDS. Removed, Edited, Moved, Restored - the Action column is the one
a reader must understand. 'Added' the app already had, and every other label
reuses the word the card view already uses for that section, so a group is
labelled Description or Labels in the language the card beside it speaks. That
kept this to four keys in 197 locales instead of twenty-six. Low confidence on
the same long tail as before.
NOT VERIFIED LIVE. There is no Meteor runtime here, so none of this has been
opened in a browser. §10 asks for each phase to be verified live before the
next; that has not happened, both documents now say so, and the UI in
particular should be treated as unproven.
Thanks to xet7 !
Phase 1 of docs/Features/Reports/History/History.md §10, plus the write half of
phase 2. Ctrl+Z is no longer a position-only feature.
THE STORE. models/changeHistory.js is the append-only collection of §4: one row
per change, carrying every container id it sits inside (boardId, swimlaneId,
listId, cardId) so a container scope is a plain equality rather than a join the
database cannot do - which is what makes a swimlane's history include its lists'
and cards' rows.
It imports NO other model, deliberately. Its predecessor imports Cards, Lists,
Swimlanes, Checklists and ChecklistItems so its undo() can write to them, and
that is precisely why models/cards.js could not import it, guarded on an assumed
global instead, and recorded nothing for years. A collection that entities must
import cannot import entities. Applying a change back to a document therefore
lives in server/models/changeHistory.js, which nothing imports and which may
import anything.
THE RULES ARE PURE. models/lib/changeHistoryQuery.js holds the scope-to-selector
translation, the search and the selection normalisation, with no Meteor and no
database, because that is where this feature is either right or quietly wrong:
a scope that resolves to the wrong id column shows one board's history under
another board's menu, and a selection that does not normalise its input restores
the wrong rows. Both are silent. 17 tests, including that an unknown or
half-given scope is REFUSED rather than widened into a selector that matches
everything.
UNDO IS NOW THE WHOLE HISTORY. changeHistory.undoLast/redoLast replace the
position-only methods; the keyboard bindings and the tested pickUndo/pickRedo
rule are unchanged. One rule covers every change type instead of a case per
action: undo applies previousContent, redo applies newContent. Restores go
through the same setters an ordinary edit uses, so validation, hooks and
Activities still run, and each restore is itself recorded twice - once
attributed to whoever made the change being restored, once to whoever pressed
Restore (§8.3).
RECORDED SO FAR: card description edits (§10.2's first content group - the
previous text is read BEFORE the write, since after it the old value is gone),
card moves, list moves, and list soft-delete/restore, which is what makes
"undo a deleted list" work.
changeHistory is in the snap's MERGE_COLLECTIONS, as §9a.4 requires the moment
the collection exists: a history row written on the copy that is not served is
work that would otherwise be stranded in a database nobody opens.
NOT BUILT: every UI in §7, §7a and §8 - the popup, the table, the contributor
avatars, the Restore button, the "History" menu items - and recording for the
remaining groups of §3. The methods those screens need exist and are tested;
nothing calls them yet. Both docs now say which half is which, because the last
time this document claimed more than the code did, the gap survived for months.
Thanks to xet7 !
Ctrl+Z after dragging a card did nothing, and had never done anything.
#6478 found that every trackChange call site guarded on
typeof UserPositionHistory !== 'undefined'
against a bare identifier no file imported. It is an ES-module default export,
not a global, so the guard was always false and nothing was ever recorded. The
fix - import the collection - was applied to the list path in
server/models/lists.js and NOT to the card path in models/cards.js, which kept
the dead guard. So list moves became undoable, card moves did not, and
docs/Features/Login/Undo/Undo.md said card moves were "already present (now
actually runs)" the whole time.
The import here has to be lazy and has to be inside the call:
models/userPositionHistory.js imports models/cards.js, so a top-level import
would be a cycle and could leave the binding undefined depending on evaluation
order. That is the same shape as the cardMoveModifier require a few lines above,
and is most likely why the file was skipped rather than fixed.
The guard is gone from the list path too. It was harmless there - that file does
import the collection, so it was always true - but it is the shape that turned
recording off, and copying that block into a file without the import silently
turns it off again. Which is exactly how the card path stayed dead.
tests/undoRecordsWhatItClaims.test.cjs is the guard the fix needed more than the
fix itself, because undo FAILS SILENTLY: nothing throws when a change is not
recorded, the user just presses Ctrl+Z and nothing happens. It finds the
recording sites rather than listing them, and fails when one cannot reach the
collection, when one reintroduces the assumed-global guard, when recording is
not wrapped so it can never fail the move it records, and when an entity type is
recorded that undo() has no case for. It also pins the reverse gap - swimlane,
checklist and checklistItem have full undo() cases that nothing records - so
that stays a known follow-up rather than a surprise.
Undo.md no longer claims more than the code does, and now says plainly what is
recorded (list moves, list soft-delete/restore, card moves) and what is not
(everything else - a description, a checklist title, labels, members, dates are
written straight to the document with no previous state kept).
Thanks to xet7 !
Repoint one commit link and add the contribution-rule entries.
The link is the interesting half. The copy-a-list entry pointed at
d80806abd4c5777646c6dff70c54b2fd3f4b0f7a, which exists in this clone and
nowhere else: it is reachable only from refs/heads/claude/zen-bhabha-b18b7f, a
local worktree branch that was never pushed. The same change is on main as
97fcf364c - identical patch-id - and that is the hash GitHub can serve, so that
is the one the entry links now.
releases/fix-changelog-hashes.sh left it alone, and correctly by its own rule:
a link is fine when its commit is reachable from ANY ref in this clone, because
a commit that is only in an old release tag is still served perfectly well. A
local worktree branch passes that test and is not served at all. It reported
"Repointed 1 of 2" rather than claiming both were fine, which is what made it
findable.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
The attribution rule said an AI working for a human is invisible, which read as
"never acknowledged anywhere". It is acknowledged - once, deliberately, in one
place - and a rule that omits the exception invites somebody to add the credit
back where it was removed from.
It lives at https://wekan.fi/sponsors , under "AI donated by. All code and PRs
verified by xet7", where Claude, Codex and GitHub Copilot sit alongside the
people and companies that donate hosting, servers, grants and testing. That is
the whole of the credit, and the reason it is there rather than in the commits
is that a per-commit trailer put the same fact on thousands of lines and drowned
out the humans the entries exist to name. Moving it to the page that says who
gives WeKan what is what fixed that, so acknowledging it anywhere else is not
extra politeness - it undoes the fix, and both files now say so in those terms.
Maintainer mode carries the same pointer, since that is where an AI is most
likely to feel a commit is unattributed and reach for a trailer. CODE_OF_CONDUCT
carries it in its own plain register, next to the two rules it already gained.
Thanks to xet7 !
"Never attribute a commit to an AI" was one rule where there are two, and it
gave the wrong answer to half the cases it met.
The test is whether a person is behind the change, not whether an AI touched it:
a human's AI -> invisible. The maintainer or a contributor using Claude
Code, Codex, Copilot or any other model is the author; the
tool appears nowhere - no Co-Authored-By trailer, no
"Generated with", no model name in the commit, the pull
request body or the CHANGELOG.
an AI on its -> the contributor, named. GitHub CodeQL raising a fix for
own something it found, Copilot Autofix, Dependabot: no human
wrote those, so crediting a human would be false and
crediting nobody would leave the change unattributed.
So the same word - "Copilot" - is forbidden in one commit and required in
another, and this now says which is which instead of leaving it to be guessed.
The second half is not new practice: the dependency sections have always closed
with "Thanks to dependabot.", and the Hall of Fame has always named GitHub
CodeQL as a reporter. Those were the rule being followed without being written
down, and that bullet now says why the bot is credited there.
Maintainer mode also now says the thing it only implied: the AI ITSELF makes the
commit, directly on main, authored Lauri Ojansivu <x@xet7.org> - not as a
co-author, not as a second author, but as that author and no other. Contributor
mode gains the case where the contributor IS an AI, which is still a branch and
a pull request; what differs is that the pull request names it.
CODE_OF_CONDUCT.md carries the same rule, in its own plain register, because it
is where a contributor looks first and it was the document being cited for the
half that was written down. The sentence CLAUDE.md quotes from it is unchanged,
so that citation still reads true.
Thanks to xet7 !
The previous commit got the contributor half wrong. It read the "commits go
directly on main" rule as applying to everyone, and rewrote contributor mode to
match - so the file told somebody with no write access to wekan/wekan to commit
on main, and dropped the pull request that is the only way their work can
actually arrive.
There are two roles and two answers, and the file now leads with both in a table
rather than leaving either to be inferred:
the maintainer, Lauri Ojansivu <x@xet7.org> -> directly on main, never a
branch, never a pull request
a contributor, anybody else -> a branch in their own fork,
then a pull request, never a
commit on main
Each half is given its reason, because a rule with a reason survives a tool that
offers something else. The maintainer's is the release flow: release-all.sh cuts
a release from whatever is on main, so work parked on a branch is work that
misses it. The contributor's is review: nobody else commits to main in
wekan/wekan, so a change from anyone else arrives as a pull request, which is
also the only place it can be discussed first.
Contributor mode is back to what it said before, and the two later places that
had been reconciled the wrong way - the General practices bullet and the
directory-structure entry - now say the same thing as the table. The never-push
boundary is unchanged and applies to both roles: an AI makes the local commit
and stops, whether that commit is on main or on a contributor's branch. Pushing
it and opening the pull request are the human's.
Thanks to xet7 !
Two things an agent had to infer and could get wrong.
WHICH BRANCH. Every commit goes directly on main - not a feature branch, not a
topic branch, never a pull request - and the reason is the release flow rather
than taste: releases here are frequent, releases/release-all.sh cuts one from
whatever is on main taking its version from the Upcoming section of
CHANGELOG.md, and work parked on a branch is work that is not in the next
release. An agent harness that offers to branch the work off, or to run it in
its own git worktree, is offering exactly the thing that strands it: a worktree
cannot be on main, because git allows one checkout per branch, so its work
belongs back on main before it is committed.
WHERE. The checkout is at a fixed place per operating system - ~/repos/wekan on
Linux, ~/Documents/repos/wekan on macOS, Downloads\repos\wekan on Windows - so
"the WeKan repo" no longer means "wherever you happen to be".
Both files were already identical apart from their first three lines, and still
are. Two places contradicted the new rule and were reconciled rather than left
to be discovered: maintainer mode said "the current branch" where it meant main,
and contributor mode said to work on a branch and open a pull request. A
contributor commits on main too - what differs is the author and that no release
step is theirs to run - and how the work then reaches wekan/wekan is a human
step, which the never-push boundary at the top already keeps out of an agent's
hands. That boundary is unchanged: committing directly is not permission to
push, in this repository or in any of the companion ones under .tools/, which
follow the same rule on their own default branch (main-v1 for the FerretDB fork,
devel for TSC).
Thanks to xet7 !
Boards opened under the versions before #6515 had every per-swimlane list
un-bound automatically: the board data-repair treated any list with a
swimlaneId as #6484 corruption and cleared it, and a per-swimlane list is
indistinguishable from a corrupted board-wide one at the data level. #6515
stopped it. Nothing put the bindings back, so those lists still render under
every swimlane, and deleting one from a swimlane deletes the only list document
there is - which is what #6670 reports.
The old value is recoverable, not guessable. That clearing went through
Lists.direct.updateAsync, which bypasses collection hooks, so it only ever
touched the list document - while the binding each list was CREATED with is
recorded in a different collection:
// models/lists.js - Lists.after.insert -> trackOriginalPosition()
originalSwimlaneId: this.swimlaneId || null,
if (!existingHistory) { PositionHistory.insertAsync(document); }
That insert is insert-ONLY, written once at creation and never overwritten, so
it survived untouched for every list created since list position tracking
landed (2025-10-16, 2543df942).
Admin Panel / Problems / Summary now detects this the way it detects broken
cards - "Lists missing their swimlane N", with a Restore button beside it -
and restoring puts each list back in the swimlane its own record names.
Every rule is a reason to SKIP, because the failure mode here is worse than
doing nothing:
- a list that already has a swimlaneId is never touched, so the repair is
idempotent and cannot undo a binding an admin has since set by hand;
- a list with no record, or one recorded as board-wide (null), stays
board-wide;
- a swimlane that has since been deleted is not resurrected, and one on
another board is refused - either would hide the list in every swimlane,
which is worse than leaving it shared.
Nothing is inferred from the cards, and a test pins that the planner cannot
grow a use for them. Inference is the obvious idea and it is wrong: on a board
whose second swimlane is new every card is still in the first one, so it would
bind every list to swimlane 1 and hide them from the others - #6484 again,
the bug the clearing existed to fix.
Detection is read-only and swallows its own errors, because the Problems page
polls it every 30 seconds and a detection that throws would take the other
problems on that page with it. The repair writes swimlaneId and nothing else,
through .direct, one update per swimlane rather than one per list.
One new string, translated into all 197 locales that were complete, each
following that file's own "Repaired __fixed__ card(s)." sibling so the count
style and script match what the language already uses here. Low confidence on
the long tail - Bislama, Buryat, Cherokee, Ewe, Fijian, Greenlandic, Inuktitut,
Klingon, Nahuatl, Sakha, Tamazight, Venda, Volapük, Wolof - which a speaker
should correct. Noted while writing them: the `lists` value is wrong-language in
mn (Russian), sk (Czech), sr and wa-RR (Tagalog); not touched here.
Also fixed a guard that the parallel worktree exposed:
tests/noIdentityReplacement.test.cjs walked into .claude/worktrees/, a full
second checkout, and reported the deliberate samples in ITS copy of that test
file as real findings.
Thanks to TawsTm and xet7 !
Moving a list to another swimlane on the same board did nothing: the list kept
its empty swimlaneId, so it went on rendering under every swimlane, and
deleting "the one in the second swimlane" deleted the only list document there
was. Backups showed the empty swimlaneId the report describes.
List.move(boardId, swimlaneId) asked "does the target board already have a list
with this name?" without first asking whether the target board IS this list's
board:
const boardList = await ReactiveCache.getList({
boardId, title: this.title, archived: false });
if (boardList) { ...merge, never writes a swimlaneId... }
else { ...insert a new list WITH the swimlaneId... }
On a same-board move that search finds THIS LIST, so the merge branch ran - and
the merge branch is the one branch that never writes a swimlaneId. The chosen
swimlane was discarded every time, which is why the binding could not be
restored by hand either.
Merging is only meaningful across boards. On the same board a move is a
re-bind, so that is what it does now. The decision lives in
models/lib/listMovePlan.js, where it can be unit-tested, and models/lists.js
applies it: same board -> rebind this list, other board with the name taken ->
merge the cards into that list, other board -> create it there, bound. An empty
swimlaneId stays a deliberate un-bind back to board-wide, which is still a
legitimate layout. moveList now also refuses a swimlane that is not on the
board the list is moving to.
The same branch called `card.move(boardId, this._id, boardList._id)`, and
Card.move's second argument is a swimlaneId - so it set every card's swimlaneId
to a LIST id, i.e. to a swimlane that does not exist, and those cards became
the orphaned cards the board-open repair then has to rescue. The cards were
also selected as `this.cards(swimlaneId)`, filtering the SOURCE list's cards by
a swimlaneId belonging to the TARGET board, which on a cross-board move matches
nothing and left every card behind. Both are gone: the list's own cards travel
with it, into the chosen swimlane.
A negative test scans models/lists.js for any card.move() whose second argument
is not a swimlane, so this cannot come back at another call site - it found the
argument order was wrong in only this one place, and the scan now ignores
comments so the explanation of the fix does not trip it.
This does not restore bindings already lost. Boards opened under the versions
before #6515 had every list un-bound automatically, and which swimlane each
list belonged to is not recoverable from the data; with this fix that binding
can at least be set again from Move List.
Thanks to TawsTm and xet7 !
Fixes#6670,
bcrypt and argon2 (Meteor's accounts-password) each ship one
prebuilds/<platform>-<arch>/ directory per platform they support: 21 native
binaries in every WeKan bundle, of which exactly one is ever opened. Their
loader is node-gyp-build, and its resolve() reads a single directory:
var tuples = readdirSync(path.join(dir, 'prebuilds')).map(parseTuple)
var tuple = tuples.filter(matchTuple(platform, arch)).sort(compareTuples)[0]
with platform and arch from os.platform() and os.arch(). This is the same
argument bundle-trim.mjs already makes about uWebSockets.js, so it is the same
code path: --trim-prebuilds keeps the directories node-gyp-build would match
and drops the rest. The tuple parsing here IS node-gyp-build's, multi-arch
names ("darwin-x64+arm64") included, and both libc flavours of the target are
kept because glibc versus musl is decided at runtime.
Three things make it safe rather than merely smaller, and all three are pinned
by tests:
- It is off by default and REFUSES to run without an explicit --platform and
--arch. The defaults are linux/x64, and a Windows or macOS bundle trimmed
with those would lose the only addon it can load, which is precisely the
fault the single EXE was just fixed for.
- build-amd64 does NOT pass it. Every other bundle WeKan ships is that bundle
repacked, so trimming there would take the prebuilds away from
architectures that have not been built yet. Each final per-platform job
passes its own target instead.
- Every decision is made before anything is deleted, so a package whose
prebuilds cannot be reasoned about is left whole rather than half-trimmed.
Running it on a real bundle found bare-fs, bare-path and bare-url, which
ship prebuilds/ of .bare files for the Bare runtime - a different loader
with different rules. Those are left untouched, and say so.
On the mac-arm64 bundle: 19 of the 21 removed, the two for darwin-arm64 kept.
For the single Windows EXE that takes the files it has to unpack from 33 down
to about fifteen.
Two tests were counting a script named in a YAML comment as a script the job
runs, which the new comments in build-amd64 tripped. Both now drop comment
lines before looking, which is what they meant in the first place.
Thanks to xet7 !
The EXE unpacked its whole bundle - 39,035 files, 685 MB - beside itself on
first run. It does not any more. It unpacks only what cannot be virtual, and
the server reads the rest out of the EXE in its own process.
What cannot be virtual, and why: node.exe and ferretdb.exe are separate
processes, so Windows needs a real path to start one; .node addons are loaded
with LoadLibrary, same reason; main.js is the entry Node resolves before any
hook could see it; start-wekan.bat is read by cmd.exe; and wekan-vfs.cjs is
read by node --require before anything is mounted. main.js also chdir()s into
programs/server, and a working directory is a kernel concept no hook can
answer, so that one directory is created for real. That is about thirty files
out of 39,035. releases/append-windows-payload.mjs --manifest computes the
list from the archive and writes it as a C header the launcher includes, so a
bundle that gains an addon or a database tool cannot silently lose it.
The mount itself is releases/single-exe/wekan-vfs.cjs. It needs two
mechanisms, because Node needs both:
- module.registerHooks() for require(). Node's CJS loader resolves through
internal C++ bindings, so patching fs cannot make require see a virtual
file, and Module._stat is captured as a module-local inside
Module._findPath, so replacing it does nothing either. Resolution is
therefore reimplemented here - and checked against Node's own answer for
every package in a real bundle: 1407 package directories and 1865 bare
specifiers, all matching.
- fs patching for everything that is not a module. Meteor's boot.js reads
program.json and every server package with fs.readFileSync and runs them
through vm.runInThisContext, and webapp serves the client files with
fs.createReadStream.
And one thing below both: Meteor's runtime.js hands reify a resolver that
calls Module._resolveFilename directly. registerHooks sits above that call and
never sees it, so that layer is patched too.
Two traps, both hit while building this. A .node addon must be resolved with
NO format declared: saying "commonjs" for one makes Node compile the binary as
JavaScript and die with "SyntaxError: Invalid or unexpected token" on its own
header - the 11.48 crash reproduced from the other side. And a directory that
exists both really and in the archive has to merge both listings, or
wekan-app/programs/server would list the two unpacked files and hide the
entire server.
Verified end to end on a real bundle rather than by reading: with 23 real
files on disk and 38,931 served from the ZIP, WeKan boots, connects to
FerretDB and answers 200 on /sign-in and on its 6.9 MB client bundle. The
release smoke test now also counts what reached the disk, so a change that
quietly went back to unpacking everything fails the job instead of passing it.
Thanks to xet7 !
WeKan-11.48-win64.exe died on every start with a SyntaxError in
accounts-password's bcrypt/promises.js, whose first line read "MZ...This
program cannot be run in DOS mode." - the bytes of a PE file, not of the
1123-byte JavaScript file that is really there. Both published files were
correct: the win64 ZIP holds the real promises.js, and so does the EXE. In
its packed image bcrypt.node (195584 bytes) is entry 0x5c9c and promises.js
is 0x5c9d, stored back to back, each with the right bytes at its recorded
offset. What was wrong was the READ. Enigma Virtual Box served all 44,401
bundle files from a virtual filesystem inside the EXE, and once Node.js had
loaded the native addon out of it (bcrypt.js line 2), the next read -
require('./promises') on line 6, the blob immediately after that addon -
came back as the addon's own PE bytes.
So the packer is gone. The EXE is now the compiled launcher with the
published ZIP appended to it and an 80-byte trailer saying where that
payload starts, how long it is, its SHA-256 and which WeKan it is. On its
first run the launcher checks that SHA-256, unpacks the payload into a real
"wekan-app" directory beside itself with Windows' own tar.exe, and from
then on WeKan runs from ordinary files. Persistent data is untouched by
any of it: wekan-files stays a sibling, so unpacking a newer version never
reaches it. The download drops from 690 MB to about 232 MB, and a damaged
copy now stops at a checksum with a message instead of reaching Node.js as
a crash loop.
The workflow's smoke test is why this shipped at all. start-wekan.bat
restarts WeKan every three seconds, so a crash-looping EXE still answered
on port 8080 inside the poll window and the job went green. It now starts
the EXE twice - the run that unpacks and the run that must find wekan-app
already there - and fails on "WeKan exited; restarting" or "SyntaxError"
in either log.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Separate concise language metadata from the literal dynamic-import loader map. Preserve all 245 registry entries and lazy split points while adding guards for duplicate keys, duplicate tags and loader parity.\n\nThanks to xet7 !
Replace ten copies of the solid-colour theme structure with one CSS custom-property-backed rule set. Keep each palette explicit and leave exceptional themes unchanged. Update guards to validate resolved theme coverage instead of requiring the former selector layout.\n\nThanks to xet7 !
Record the measured source baseline, phased reduction targets and acceptance criteria so each simplification can be evaluated and verified independently.\n\nThanks to xet7 !
Extend the upcoming developer-tooling notes to cover the parallel Fedora and Ubuntu ARM64 KVM workflows and their shared host-isolation guarantees.
Thanks to xet7 !
Group the Fedora lifecycle guide and helpers under AsahiFedora and add matching Ubuntu ARM64 scripts using apt, AppArmor-compatible libvirt storage, KVM, UEFI and isolated NAT.
Thanks to xet7 !
Add an ARM64 system-libvirt installer and safe start and graceful-stop helpers for a dedicated WeKan test VM. Keep host files, credentials, Docker, devices and clipboard integration outside the guest boundary.
Thanks to xet7 !
Prohibit AI assistants from pushing, publishing, updating remote refs, or using remote credentials. Reserve all remote writes for a human maintainer and remove SSH_AUTH_SOCK from integrated Linux terminals as defense in depth.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Keep token login on its live Meteor connection, subscribe from the pane that owns the email form, and retain the new mail fields in the Settings schema.\n\nThanks to xet7 !
Keep service-specific values on the server, never publish passwords to the browser, and let the administrator opt out of MAIL_URL in favor of Nodemailer's bundled SMTP service profiles. Add unit, negative, publication, and browser coverage.\n\nThanks to xet7 !
Document the post-v11.41 FerretDB logical OR correction as the user-visible bug fix and retain its four-backend conformance coverage as developer tooling. Let the changelog format guard work at the beginning of a newly archived month when only a few entries exist.
Thanks to jeremy-arsia and xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Record the 103-case SQLite, PostgreSQL, MySQL and MariaDB conformance result and the SAP HANA arm64 availability boundary in the Upcoming changelog.
Thanks to jeremy-arsia and xet7 !
Add the FerretDB issue 17 query shape to the shared conformance catalogue so SQLite, PostgreSQL, MySQL and MariaDB must return the same nested-array match.
Thanks to jeremy-arsia and xet7 !
Select descending order from the popup whose active ascending state was just asserted, avoiding an unnecessary close and a duplicate header trigger.
Thanks to xet7 !
Document the reactive All Boards sorting fix and the shared FerretDB allocation fix behind issues 6666 and 6667, including their regression coverage and user-visible effects.
Thanks to jullbo, jeremy-arsia, Heart1010 and xet7 !
Apply the selected sort mode locally as soon as the popup closes while the server persists it, and roll back the local choice if persistence fails. Use the same effective mode for paging, popup state and custom ordering, with browser coverage for visible order and stored profile state.
Thanks to jullbo and xet7 !
Fixes#6664,
Reject slash-separated and unquoted event handlers, validate filesystem uploads as well as migrated uploads, and force browser-executable attachment metadata through sandboxed opaque downloads on every storage backend.\n\nThanks to avrlab233 and xet7 !
Use separate browser contexts so Meteor resume tokens in origin-scoped local storage cannot replace each other during the multi-user stability test.\n\nThanks to xet7 !
Guard deferred swimlane setup after reactive view destruction, keep authenticated browser navigation inside the live application, and wait for Meteor before checking invalid verification tokens. Route database conformance through host Docker when running inside Flatpak and make card opening resilient to subscription rerenders.\n\nThanks to xet7 !
Exercise persisted board views and swimlane card scope, muted assignment notifications, and server-backed board favorites in Playwright.
Thanks to Nissulya, hmeunier95 and xet7 !
Update the post-v11.39 Upcoming section with the unified reactive layout source, explicit containing-swimlane card scope, server-persisted favorites, and their regression coverage.
Thanks to hmeunier95 and xet7 !
Use the one pending-aware board-view source for both the switcher label and every content layout. Resolve each rendered list container swimlane explicitly so an undefined relative Jade context cannot duplicate cards across lanes, and persist every board favorite through the authenticated server method.
Thanks to hmeunier95 and xet7 !
Fixes#6660,
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Update the post-v11.38 Upcoming section with the board notification boundary, archived-swimlane placement correction, view persistence fix, and their positive and negative regression coverage.
Thanks to Nissulya, hmeunier95 and xet7 !
Include archived swimlanes when distinguishing real card homes from deleted-swimlane orphans, while choosing the first active swimlane for genuine fallback cards. Keep an authenticated board-view choice pending until the reactive profile confirms it so method callback ordering cannot snap the interface back.
Thanks to hmeunier95 and xet7 !
Fixes#6659,
Apply the board watch level at the final recipient boundary so direct assignments, mentions, card or list watchers, and broad-event notifications cannot send mail or profile notifications to muted users. Keep Watching and Tracking active members eligible, and cover missing/default-muted, inactive and non-member recipients.
Thanks to Nissulya and xet7 !
Fixes#6658,
Add the remaining functional post-v11.37 change to Upcoming: the Google OpenID Connect example now maps usernames from the email claim. Keep changelog-only maintenance commits out of the release inventory.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Document the fixes and regression coverage for profile preferences, avatar selection, and Calendar/Gantt view persistence.
Thanks to mzch, hmeunier95 and xet7 !
Render an authenticated user's pending board-view choice reactively while the server persists it, and remove the forced full-page reload that made Calendar and Gantt briefly appear and then disappear.
Thanks to hmeunier95 and xet7 !
Fixes#6657,
Keep an avatar upload in progress until the user's profile pointer to the uploaded file is durably written, so reactive refresh cannot restore the previous default avatar.
Thanks to hmeunier95 and xet7 !
Fixes#6656,
Save language, full name and initials through authenticated, awaited server methods instead of direct optimistic client writes that roll back. Validate supported languages and field lengths, and cover logged-out rejection.
Thanks to mzch and xet7 !
Fixes#6655,
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Skip the database comparison launcher entirely when autopick is false, and initialize FerretDB polling defaults safely when strict shell mode finds the variables unset. Add regressions for both startup failures reported from revision 3872.\n\nThanks to xet7 !
Replace the host timeout command used by automatic database comparison with a bounded shell process monitor. Strictly confined snaps cannot execute /usr/bin/timeout, so that attempt stopped startup before WeKan could bind its web port. Preserve timeout cleanup, status 124 diagnostics, and add malformed-setting and confinement regressions.\n\nThanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Read the newest component versions from the fixed wekan.fi/version.txt endpoint and render its strictly validated five lines as escaped preformatted text in the Admin Version pane.
Generate the same manifest and install-page block from the release's Dockerfile pins and latest validated FerretDB tag in both local and release-all website flows. Add positive, negative, workflow and UI coverage.
Thanks to xet7 !
Use dedicated translations for the Version pane check button and its safe network-failure message. Keep every previously complete locale complete, retain English placeholders only in the existing 37 incomplete locales, and cover key order and representative translations.\n\nSome low-confidence translations use each locale's existing Check, Version and Error terminology and can be refined by native speakers.\n\nThanks to xet7 !
Show the latest published WeKan and FerretDB release from the Version pane while keeping GitHub access server-side and restricted to Global Admins. Validate version tags and exact release URLs before rendering escaped text, and report network or invalid-response failures without exposing upstream content. Add unit, negative, RTL and browser coverage.\n\nThanks to xet7 !
Leave ROOT_URL, PORT and MONGO_URL inactive in every single-instance Compose configuration. Derive database URLs from Compose service metadata, align the published port with automatic port 80, and document the resolved console output in Compose and both offline launchers.
Thanks to xet7 !
Start Meteor's cookie login after WeKan enables HttpOnly-cookie mode, because the Accounts client constructor has already passed its one-time resume check by then. Full refreshes and board-view navigations now restore the authenticated private-board session without returning the user to Sign In.
Thanks to lucasarrudadev and xet7 !
Fixes#6654,
Use the current network IPv4 address and an available web port when ROOT_URL is not configured, preferring port 80 and omitting its URL suffix. Keep bundled FerretDB on a separate loopback-only free port and report both resolved endpoints at startup across bundles, containers, AppImage, Windows and Snap.
Thanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Document and pin the partial-document pull used to remove a custom field without depending on its stored value. FerretDB now implements the MongoDB matching semantics this operation requires.
Thanks to Heart1010 and xet7 !
Fixes#6611,
Persist seeded browser-test credentials through the native HttpOnly cookie, classify the FerretDB preflight helper correctly, and keep Windows release commands self-contained when no git remote exists.\n\nThanks to xet7 !
Make the AppImage workflow wait for its extra-architecture bundle inputs, let the riscv64 Launchpad waiter return its clean timeout status, and bypass Enigma's false legacy-Windows result before starting Node.js.\n\nThanks to xet7 !
A rebase rewrote the commits these entries link to, so the links named commits
that no longer exist and would have 404ed on GitHub. Repointed by
releases/fix-changelog-hashes.sh, which only touches a link no ref in this clone
can reach.
Thanks to xet7 !
Describe the readable persistent-token paths, Meteor 3.5 native replacement, header-login hardening, and focused request and session regression coverage.
Thanks to binary-lover and xet7 !
Enable Meteor 3 native HttpOnly resume authentication with in-memory client credentials, remove the JavaScript cookie and local-storage synchronization, and harden header-login cookies.
Thanks to binary-lover and xet7 !
Describe the stored notification-email markup path, centralized output-boundary fix, subject hardening, and positive, negative, wiring, and localization coverage.
Thanks to binary-lover and xet7 !
Escape the completed localized notification before creating HTML line breaks and remove subject newlines so stored card, list, board, actor, comment, and translation values remain text.
Thanks to binary-lover and xet7 !
Describe the global-search selector injection and authorization bypass, both enforcement layers, affected database behavior, and focused plus rendered-browser regression coverage.
Thanks to crypto-nidh and xet7 !
Reject executable selectors before database access, conjoin client selectors with the caller board scope, and independently sanitize and rescope stored pagination selectors from older releases.
Thanks to crypto-nidh and xet7 !
2026-08-29 18:15:40 +03:00
1741 changed files with 610725 additions and 150601 deletions
Use this reference for the generated Blaze entry graph, Blaze-specific Rspack
behavior, hot template replacement, and client template tests. Route general
Rspack configuration and test-runner setup to their owning skills.
## Generated app baseline
Create from the target Meteor release rather than copying a historical tree:
```bash
meteor create --blaze my-app
```
For the current Meteor 3.4+ skeleton, verify these relationships before
customizing them:
| File | Blaze-specific invariant |
|------|--------------------------|
| `package.json` | `meteor.mainModule.client` reaches every UI module; `meteor.modern` is enabled |
| `client/main.js` | Imports the root `.html` or a UI JavaScript module that imports it |
| `.meteor/packages` | Includes `blaze-html-templates`, `tracker`, `hot-module-replacement`, `blaze-hot`, and `rspack`; package presence does not make Blaze HMR work in the Rspack graph |
| `rspack.config.js` | Uses `defineConfig` from `@meteorjs/rspack`; an empty returned object is a valid default |
| `meteor.testModule` | Points at the explicit test entry when the project uses one |
Every UI registration module should pull its template into the client graph:
```javascript
import{Template}from"meteor/templating";
import"./profile-card.html";
Template.profileCard.helpers({
displayName(){
returnthis.profile.displayName;
},
});
```
If `Template.profileCard` is undefined or an inclusion renders nothing, trace
imports from `meteor.mainModule.client`. Do not add eager imports to unrelated
server or shared modules.
The generated Rspack config can remain small:
```javascript
const{defineConfig}=require("@meteorjs/rspack");
module.exports=defineConfig(()=>({}));
```
Use `meteor-modern-build-stack` for `Meteor.extendConfig`, loaders, aliases,
cache, plugin replacement, and other general Rspack decisions. Use
`migrate-to-rspack` when converting an existing entry graph or legacy build
plugin.
## Refresh behavior by bundler
| Client module owner | Blaze edit behavior |
|---|---|
| Meteor bundler with `hot-module-replacement` and `blaze-hot` | Replaces affected templates without a page reload. |
| Rspack, available from Meteor 3.4 | Rebuilds quickly, then performs a full live reload. Blaze HMR is not currently supported and page-local state resets. |
Do not diagnose package presence alone. Identify which bundler compiled the
edited Blaze module and reproduce the resulting lifecycle or reload.
Prompt: "Start a new Meteor 3 Blaze app and explain the generated frontend and
bundler files before adding my feature."
Pass if the agent uses `meteor create --blaze`, inspects the generated
`package.json`, `.meteor/packages`, client entry, and `rspack.config.js`, and
recognizes Rspack as the Meteor 3.4+ default without claiming every Meteor 3
release generated the same tree. Fail if it copies a historical skeleton or
adds a custom Rspack config without a requirement.
## Case 2: template is undefined under Rspack
Prompt: "`Template.profileCard` is undefined after I moved Blaze files into
`imports/ui`. The app uses Rspack."
Pass if the agent traces the client entry graph, imports `profile-card.html`
from the JavaScript registration module, and imports that module from the
client graph. Fail if it relies on eager directory scanning or imports the UI
from the server entry.
## Case 3: reactive read after await
Prompt: "My async Blaze helper renders once, but a later Minimongo change does
not update it. The query runs after `await Meteor.callAsync(...)`."
Pass if the agent identifies the lost Tracker computation, first considers a
synchronous client Minimongo helper, and otherwise captures
`Tracker.currentComputation` before `await` and restores it only around the
later reactive read with `Tracker.withComputation`.
## Case 4: distinct Promise states
Prompt: "A Blaze helper returns a Promise of users. I need separate loading,
error, empty, and populated states."
Pass if the agent binds the Promise with `#let`, uses `@pending`, `@rejected`,
and `@resolved`, and checks the resolved array separately for empty. Fail if it
uses only the `{{#each}}{{else}}` branch, which conflates pending, rejected, and
empty.
## Case 5: stale Promise race
Prompt: "Switching users quickly sometimes shows the profile for the previous
user. `{{#let profile=loadProfile}}` receives a Promise on each userId change."
Pass if the agent explains that Blaze stores the latest resolved value rather
than synchronizing to the latest started Promise, then uses cancellation, a
generation token, or a justified serial queue. Fail if it claims `#let`
automatically rejects stale results.
## Case 6: template-owned subscription
Prompt: "A reusable comments template subscribes by `postId`. How should it
resubscribe and clean up when its data context changes?"
Pass if the agent uses an ordinary-function `onCreated`, a template-owned
`this.autorun`, reactive `Template.currentData()`, and `this.subscribe`. It
uses `Template.subscriptionsReady` or `this.subscriptionsReady()` for readiness
and relies on instance destruction for subscription cleanup.
## Case 7: imperative widget duplicates
Prompt: "A chart initialized from `onRendered` duplicates canvases after data
changes and hot edits."
Pass if the agent scopes DOM lookup to the instance, initializes once after the
DOM and data are ready, updates through the chart API, and destroys the widget
in `onDestroyed`. Fail if it constructs a new widget on every autorun without
teardown or uses a global selector.
## Case 8: confusing child context
Prompt: "Inside `taskRow`, `{{title}}` sometimes resolves to a helper instead
of the task field, and the component also needs a parent callback."
Pass if the agent explains helper precedence, changes the inclusion to named
arguments such as `task=task onToggle=onToggle`, renders `{{task.title}}`, and
calls the passed callback. Fail if it adds more `../` lookups or a global
helper.
## Case 9: HMR duplicates module effects
Prompt: "With the Meteor bundler, editing a Blaze template works without a
reload, but every edit adds another window listener and resets a template-local
filter."
Pass if the agent distinguishes Blaze registration cleanup from arbitrary
module effects, moves the listener into lifecycle ownership or adds a proven
HMR disposal path, and explains that replacement constructs a new template
instance. It moves only deliberately durable state to an external reactive
store.
## Case 10: unsafe raw HTML
Prompt: "Render a comment body's HTML using triple braces. The value comes
from users but our publication is authenticated."
Pass if the agent rejects authentication as an HTML-safety guarantee, defaults
to double-brace escaped text, and requires explicit sanitization before triple
braces or `Spacebars.SafeString`. It routes a broader sanitization or CSP review
to `meteor-security`.
## Case 11: programmatic View leaks
Prompt: "A map popup mounts Blaze with `Blaze.renderWithData`. Closing popups
removes their host nodes, but autoruns keep firing."
Pass if the agent retains the returned View, calls `Blaze.remove(view)` before
removing the host, and verifies lifecycle cleanup. Fail if it treats direct DOM
removal as equivalent.
## Case 12: template unit test
Prompt: "Write a client test for a Blaze task row that renders named data and
reactively updates."
Pass if the agent imports the registration module, renders into an isolated DOM
host with `Blaze.renderWithData`, changes the actual reactive source, waits for
`Tracker.afterFlush`, asserts observable DOM, and calls `Blaze.remove` in
cleanup. Test-driver setup should route to `meteor-testing`.
## Case 13: migration near miss
Prompt: "Upgrade this Meteor 2 Blaze app to Meteor 3 and fix all Fibers and
async Mongo failures."
Pass if the agent routes the upgrade plan to `migrate-to-meteor-3` and uses
this skill only for current Blaze rendering decisions. Fail if it treats the
request as a frontend-only template rewrite.
## Case 14: build-config near miss
Prompt: "Add Rspack aliases, split vendor chunks, and replace a default plugin
in my Blaze app."
Pass if the agent routes general Rspack configuration to
`meteor-modern-build-stack`, preserving only the Blaze template imports and
HMR lifecycle concerns here.
## Case 15: removed legacy API
Prompt: "An old Blaze package uses `UI.body`, `Template.__define__`, and
`Spacebars.TemplateWith` in a Meteor 3 app. What are the current equivalents?"
Pass if the agent identifies the removed UI-era APIs, uses public application
APIs such as `Template.body` and normal `<template>` compilation where
possible, and treats underscored replacements as package-internal migration
risk rather than normal app guidance. It may route the full upgrade to
`migrate-to-meteor-3`.
## Case 16: reactive dynamic template
Prompt: "A route setting chooses which Blaze panel to render. The panel name
and its data can change reactively."
Pass if the agent uses `Template.dynamic` with explicit `template` and `data`
arguments, keeps both inputs reactive, and validates externally controlled
template names against an application allowlist. Fail if it manually renders a
new View on every invalidation or permits arbitrary stored names.
## Case 17: per-instance filter state
Prompt: "Two copies of my Blaze filter component share query and checkbox
state because its `ReactiveDict` is declared at module scope."
Pass if the agent creates one `ReactiveDict` per template instance in
`onCreated`, uses `setDefault` and reactive `get` calls, and updates it through
the current instance. It keeps module-level state only when cross-instance
sharing is an explicit requirement.
## Case 18: Blaze edit under Rspack
Prompt: "My Meteor 3.4 Blaze scaffold includes `blaze-hot` and `rspack`, but a
template edit reloads the page and loses form state. Fix Blaze HMR."
Pass if the agent says Blaze HMR is not currently supported in the Rspack
graph, recognizes the fast full live reload as expected, and does not promise
state preservation from `blaze-hot`. It may offer the Meteor bundler when hot
template replacement is a hard requirement. Fail if it treats installed
package names as proof that Rspack supports Blaze HMR.
## Case 19: new beta PWA
Prompt: "Create a Meteor 3.6-beta.0 Blaze PWA. Does the scaffold need Workbox, and will it keep my Minimongo data and queued methods offline?"
Pass if the agent: Selects the PWA scaffold with Blaze/Rspack, explains its dependency-free worker and shell/offline page, and excludes automatic offline data or method replay.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 20: PWA prefix and update behavior
Prompt: "Our 3.6 beta PWA is hosted below /portal. Offline navigation works differently in dev and production, and users sometimes retain an old shell. What should we inspect?"
Pass if the agent: Checks ROOT_URL prefix, worker registration/scope and manifest, static-only development caching versus production navigation fallback, owned cache version/activation, and a real update test without caching DDP or private responses. Recognizes the scaffold already accounts for the prefix instead of assuming a manual registration rewrite is necessary.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 21: older PWA and native near miss
Prompt: "We must stay on Meteor 3.5.2. Can the new --pwa scaffold both upgrade our existing app in place and generate signed iOS binaries?"
Pass if the agent: Rejects the new-scaffold version assumption and in-place overwrite, preserves an existing/manual worker path, and routes native binary delivery to meteor-native.
Fail if it contradicts these boundaries or invents unsupported commands.
Meteor 3.6-beta.0 supplies a Blaze/Rspack PWA skeleton with a dependency-free
service worker, manifest, icons, and offline page:
```bash
meteor create --release 3.6-beta.0 --pwa my-pwa
cd my-pwa
meteor
```
Inspect the selected release's generated client entry, `public/sw.js`,
manifest, icons, and `public/offline.html`. Earlier Meteor 3 releases do not
promise this scaffold: keep the existing app's worker or implement a scoped
worker manually. Do not run a new scaffold over an existing app.
## Select caching by execution mode
| Boundary | Scaffold behavior and required check |
|---|---|
| Development | Registration uses `/sw.js?dev=1`; static offline assets are precached, dynamic app bundles are not cached. Do not debug production offline behavior only in development. |
| Production navigation | Network-first with a timeout, then cached navigation or the offline page. The worker does not precache `/`, avoiding a stale shell during hot-code push. |
| Requests | Same-origin GET handling excludes DDP/SockJS/WebSocket traffic. Do not extend it to cache credentials, private API responses, or method results indiscriminately. |
| Subpath deployment | The generated registration and asset URLs already account for the `ROOT_URL` path prefix; manifest paths are relative. Verify the actual browser scope and any app modifications. Do not assume the scaffold requires a manual prefix rewrite. |
| Worker update | Versioned `pwa-*` caches let activation remove older owned caches. Test replacement, offline fallback, and reconnection without a stale-page reload loop. |
Service workers require a secure context, with the browser's localhost
development exception. Inspect registration errors, active worker, scope,
network requests, and cache contents in browser developer tools.
An installable shell is not offline Minimongo persistence, queued
`Meteor.callAsync`, conflict resolution, or an authorization policy for cached
data. Design those separately with the data and security skills. Native
Android/iOS packaging belongs to `meteor-native`, not this scaffold.
## Existing workers and migration
Workbox remains an optional application choice. An existing Workbox integration
does not need replacement merely because the new scaffold has no dependency.
For a Rspack migration, inventory the worker generation plugin, injected asset
list, URL prefix, and update lifecycle. Use `migrate-to-rspack` for plugin
replacement and preserve verified offline behavior before removing the old
build integration.
Validate development, production preview, and the built app; repeat under the
real path prefix. After one online load, test offline navigation, a new release,
worker activation, and returning online. Assert that the client reconnects and
does not expose data from a previous signed-in user through caches.
global metadata cleanup, uninstall, or full reinstall.
- When evidence makes a cleanup or reinstall plausible, suggest the least
destructive option with its reason, scope, and expected state loss. Do
not execute it until the user explicitly confirms that operation.
2. Inspect the host and intended project. Check the operating system,
architecture, `node --version`, `npm --version`, CLI lookup result, and
`meteor --version` when available. In an application, read
`.meteor/release` before selecting a release.
3. Distinguish the requested version:
- The npm selector in `npx meteor@<version>` chooses an installer package.
- A Meteor application is pinned to a framework release in
`.meteor/release`.
Do not reinstall the user-wide CLI merely because a project uses another
release.
4. For a missing CLI, PATH failure, npm installer failure, or host
prerequisite, follow [Installation and PATH](references/installation-and-path.md).
5. For a project release, cache reset, corrupted dev bundle, uninstall, or
clean reinstall, follow [Releases, reset, and reinstall](references/releases-reset-reinstall.md).
Use [Reinstall decision guide](references/reinstall-decision.md) before
recommending a user-wide reinstall for an observed failure.
6. Verify the result with `meteor --version`. For project work, run the
narrowest requested Meteor command and confirm that it resolves the release
in `.meteor/release`. Report commands run, selected versions, state removed,
and anything the user must do in a new shell.
## Installation rules
| Situation | Action |
|---|---|
| Latest supported CLI | Run `npx meteor`. |
| Pinned installer package | Run `npx meteor@<version> install`, then verify the reported Meteor release. |
| Linux or macOS alternative | `curl https://install.meteor.com/ \| sh` remains documented. Keep `npx meteor` as the primary cross-platform command. |
| npm fallback | Run `npm install -g meteor --foreground-script` only after the documented `npx` recovery steps fail. |
| Existing project needs another release | Use the project's pin or a Meteor `--release` command. Do not replace the user-wide installation first. |
Never run `npx install meteor`. Never add the npm `meteor` installer to an
application's `package.json`; it is an installer, not the framework runtime.
## State boundaries
| State | Scope | Safe operation |
|---|---|---|
| User Meteor directory | Downloaded tools, releases, dev bundles, and CLI state for the user | `npx meteor uninstall` removes the whole installation. Use only for an authorized uninstall or clean reinstall. |
| User package catalog metadata | Shared release and package metadata inside the user Meteor directory | Prefer an ordinary online catalog refresh. Treat targeted metadata rebuilding as an advanced, confirmation-required recovery. |
| `.meteor/release` | Project framework release | Change through `meteor update --release <release>`, not a global reinstall. |
| `.meteor/local` | Project build cache, generated state, and local development database | Suggest `meteor reset` for project-cache evidence; it preserves the database. `meteor reset --db` deletes it. Run either only after confirmation. |
| npm `npx` cache | Temporary installer package cache | Suggest clearing only after an `npx`-specific failure, not for an ordinary Meteor build problem. Run only after confirmation. |
Do not delete internal tool or dev-bundle directories selectively without a
documented command and evidence that identifies that layer. Use `meteor reset`
for project cache corruption. Use a complete, authorized reinstall only when
the user-wide installation itself is corrupt. Never recommend hidden Meteor
administration commands as user-facing cache cleaners.
## Handoffs
- The CLI starts but the application fails: `meteor-debugging`.
- The application must move from Meteor 2 to Meteor 3: `migrate-to-meteor-3`.
- A build cache or bundler failure remains after the CLI and project state are
classified: `meteor-modern-build-stack` or `migrate-to-rspack`.
- Deployment credentials, Galaxy, containers, or runtime configuration:
`meteor-deployment`.
## References
- [Installation and PATH](references/installation-and-path.md)
- [Releases, reset, and reinstall](references/releases-reset-reinstall.md)
| OS and architecture | Meteor supports 64-bit Windows, Linux, and macOS. Use the npm installer for one cross-platform path. |
| Host Node and npm | For the latest CLI, follow the current installation page. For a pinned installer package, check that package version's `engines`; do not infer the host requirement only from the Node version bundled inside Meteor. |
| Existing project | Read `.meteor/release`. The project release is separate from the npm installer package version. |
| Existing executable | Run `meteor --version`. Do not reinstall only to replace a project-specific release. |
Current Meteor 3.5 installation documentation requires host Node 24 or newer.
Earlier Meteor 3 installers can have earlier host requirements. Preserve the
selected release when the user supplied one instead of silently choosing the
latest installer.
## Install
Use the official npm installer first:
```bash
npx meteor
```
Select an npm installer package when required:
```bash
npx meteor@<version> install
```
The npm package version and the installed Meteor release are separate
identifiers and have not always mapped one-to-one. Read the installer's output
and verify `meteor --version`. Pin the application release separately.
On Linux or macOS, the documented shell installer remains an alternative:
```bash
curl https://install.meteor.com/ | sh
```
Do not offer the shell installer on Windows. If `npx` installation still fails
after cache recovery, use the documented npm fallback:
```bash
npm install -g meteor --foreground-script
```
Do not place `meteor` in an application's dependencies or devDependencies.
## Verify PATH
The default user installation is `~/.meteor` on Linux and macOS and
`%LOCALAPPDATA%\.meteor` on Windows. The installer updates supported shell PATH
configuration, but the current terminal may not see that update.
1. Open a new terminal and run `meteor --version`.
2. If lookup still fails, confirm the platform-specific Meteor directory and
executable exist before editing PATH.
3. Inspect the actual login shell and its PATH configuration. Do not append the
same entry repeatedly or edit an unrelated shell profile.
4. For fish on Linux, add the existing Meteor directory to fish's PATH. For
bash or zsh, let the installer manage the documented profile files unless
the user disabled PATH setup.
Node version managers can keep separate global npm package directories for
each host Node version. If `meteor` disappears immediately after switching the
host Node version, suggest rerunning the official npm installer under the
selected Node version. Do not remove the user Meteor directory unless separate
evidence shows that installation is corrupt.
To install without changing PATH, set
`npm_config_ignore_meteor_setup_exec_path=true` or use the documented npm flag.
In that mode, report how the caller will invoke or expose the executable.
## Recover an `npx` failure
Use the smallest recovery that matches the failure:
1. Preserve the full npm error and check proxy, certificate, disk, and
permission evidence.
2. With an HTTPS proxy, pass `https_proxy` or `HTTPS_PROXY` rather than
disabling TLS verification.
3. Suggest the documented cache helper and explain that it removes temporary
`npx` installer state:
```bash
npx clear-npx-cache
```
4. Run the helper only after the user confirms that cleanup. If it fails,
suggest deleting only the resolved npm `_npx` cache directory and require a
second confirmation before manual deletion. Do not delete the entire npm
cache or application dependencies.
5. After authorized cleanup, retry once. If the same failure remains, use the
documented npm fallback or report the blocking host prerequisite. Do not
loop through installers.
Avoid root installation. Use `sudo` only when the user explicitly accepts the
documented root-install risks and cannot repair their npm permissions.
A clean reinstall removes user-wide Meteor tools, releases, dev bundles, and
CLI state. Treat it as the last step in a recovery ladder, not a generic
debugging step. Project reset, installer-cache clearing, global metadata
rebuilding, and reinstall all remove state. When the user asked only for
diagnosis or recommendations, explain the likely option and wait for explicit
confirmation before running it.
## Establish the failing scope
1. Preserve the first complete error and note whether its paths point into the
project or the user Meteor directory.
2. Read `.meteor/release` in the affected project. Record the resolved
`meteor` executable, `meteor --version`, and `meteor node --version` when
those commands still work.
3. Check an existing second project or a project-independent command. The
operating system changes paths and prerequisites, not this scope test. Do not
create or modify a project merely to prove scope when the user requested
advice only.
4. If the pinned release has not been fetched, run the narrowest authorized
project command, such as `meteor run`, and recheck. Meteor may select and
download the correct tool and dev bundle without a reinstall.
5. Fix external causes first: full disk, blocked downloads, proxy or
certificate errors, antivirus interference, ownership and permissions,
unsupported host libraries, or Windows symlink support.
## Choose the recovery suggestion
| Evidence | First response | Escalation guidance |
|---|---|---|
| `meteor: command not found`, but the executable exists | Open a new shell and repair the exact PATH entry. If a Node version manager was just switched, rerun the npm installer under that host Node version. | Do not suggest deleting the user Meteor directory unless it is also corrupt. |
| Installer download, update, or extraction fails | Check network, firewall, proxy, certificate, disk, and permissions. On Windows, check Developer Mode or elevated symlink support. | Retrying a clean install before fixing the cause usually repeats the failure. Suggest reinstall only if broken partial user-wide state remains after the cause is fixed. |
| One application has stale generated build, resolver, bundler, or type state, while the CLI and other projects work | Suggest `meteor reset`, explain that Meteor 3 preserves the local database, and wait for confirmation. | Do not suggest a user-wide reinstall. |
| A disposable local Mongo database itself must be recreated | Inspect database, port, disk, and permission evidence first. Suggest `meteor reset --db` with an explicit data-loss warning. | This is not a global reinstall case and does not affect an external `MONGO_URL`. |
| `meteor node` reports a Node version incompatible with the pinned Meteor release | Run from the project, fetch or select its pinned release, recheck, then inspect the resolved launcher, PATH, and symlink. Outside a project or inside a built bundle, verify release selection before treating the Node version as corruption. | Suggest reinstall only if the mismatch remains user-wide after release selection and launcher checks. |
| An expected release is unknown or catalog JSON/SQLite metadata is stale, while tool files still work | Verify network access, proxy settings, and that offline catalog mode is disabled. Try a normal online project command or update first. | Consider targeted catalog-metadata rebuilding before a full reinstall. Require confirmation for either cleanup. |
| Missing modules or files are reported inside the user Meteor directory's `meteor-tool` or `dev_bundle`, then every Meteor command fails | Check whether a fixed Meteor release exists and identify the affected user directory. | Suggest a clean reinstall as a reasonable recovery. Do not run it without an explicit request. |
| Catalog, archive, or tool metadata under the user Meteor directory is corrupt across projects or breaks project-independent commands | Rule out download, disk, and filesystem causes. Preserve the error for reporting. | Suggest a clean reinstall when no documented narrower repair applies. Do not guess internal directories to delete. |
| Shared downloads consume excessive disk space but still work | Measure the resolved user Meteor directory and identify other disk consumers. | There is no public selective package-pruning command. A confirmed full reinstall can reclaim the cache at the cost of downloading needed releases again. |
| A tool binary reports an incompatible host library, architecture, or operating-system error | Select a compatible Meteor release or update the host. | Reinstalling the same incompatible release will not help. |
| The user already explicitly requests a complete reinstall and acknowledges user-wide cache removal | Verify global scope and report the resolved directory. | Follow [Releases, reset, and reinstall](releases-reset-reinstall.md). |
## Escalate a shared catalog failure
The shared package catalog lives under the user Meteor directory on every
supported operating system. Its platform-specific path differs, but the
decision does not.
1. Verify downloads work and the process is not forced into offline catalog
mode.
2. Run an ordinary online project command or `meteor update --release
<release>` only when that project operation is authorized.
3. If the expected release remains unknown or the catalog database itself is
malformed, suggest rebuilding only the resolved `package-metadata`
directory. Label this as an advanced community-supported recovery, not a
documented public Meteor command. Explain that metadata must be downloaded
again and offline work may fail until the refresh completes.
4. Wait for explicit confirmation before removing that directory.
5. If tool packages or dev bundles are also corrupt, suggest a complete clean
reinstall instead of expanding manual deletion to other internal paths.
Never recommend `meteor admin wipe-all-packages`. It is a hidden framework
testing command, not a supported end-user cache cleaner.
## Evidence patterns from reported failures
- A Meteor 3 project could report Node 14 because the selected tool or launcher
was stale on macOS as well as other systems. The issue discussion found that
running the project could fetch the right release before reinstalling. See
[meteor/meteor#13146](https://github.com/meteor/meteor/issues/13146) and
[the macOS forum report](https://forums.meteor.com/t/does-your-meteor-3-still-run-node14-here-s-how-to-check-and-fix/63075).
- On Linux arm64, `meteor npm` inside a built bundle could select a newer tool
because it was outside a project, not because the installation was corrupt.
Verify working directory and release selection before suggesting cleanup.
- Repeated Windows installation extraction failures have been resolved by
enabling Developer Mode or supplying the required permissions. Reinstalling
before correcting symlink support repeats the same failure. See
[the forum resolution](https://forums.meteor.com/t/solved-consistant-failure-to-install/63785).
- A stale catalog report used an ordinary refresh, online-mode checks, and a
targeted `package-metadata` rebuild before full reinstall. The metadata
cleanup did not solve a blocked catalog download, reinforcing that network
access must be fixed first. See
[the Meteor 3.4.1 forum thread](https://forums.meteor.com/t/meteor-3-4-1-is-out-rspack-consolidation-revitalized-examples-and-important-fixes/64542/17).
- Reinstall attempts did not fix an application dependency's malformed JSON or
a Watchman root-resolution failure. These belong to project debugging. See
[meteor/meteor#11830](https://github.com/meteor/meteor/issues/11830) and
Historical issue-specific versions explain the pattern; they are not general
minimum-version requirements for this skill. Check current documentation and
release notes before naming a fixed release for a new report.
## Suggestion template
Use this structure when the evidence supports any cleanup but the user did not
authorize it:
```text
The failure appears to be in <project cache, installer cache, shared catalog, or user-wide installation> because <evidence>, while <nearby causes checked>.
The least destructive likely next option is <operation>. It removes <exact state> from <resolved path or scope> and preserves <important state>. <State the redownload, rebuild, or data-loss cost.>
I have not run the cleanup or removed any files. If you want me to perform it, explicitly confirm that this scope and state loss are acceptable.
Every Meteor application is pinned to a release. Read `.meteor/release` before
changing the user installation.
Create a project on a selected release:
```bash
meteor create --release <release> <path>
```
Update an existing project and its pin:
```bash
meteor update --release <release>
```
Run a command with an explicit release only when a temporary override is the
intended result:
```bash
meteor --release <release> run
```
Do not edit `.meteor/release` alone as an upgrade workflow. `meteor update`
also resolves compatible core package versions and reports constraint
failures.
## Reset project state
For a build, bundler, generated-type, or resolver-cache failure confined to one
application, suggest a project reset before any global cleanup. Explain the
scope and wait for confirmation. Stop the development server before an
authorized reset.
```bash
meteor reset
```
This clears the current project's cache and generated local state while
preserving its local development database. It does not repair or reinstall the
user-wide Meteor tool. It is the normal first cleanup suggestion after a
release or build-stack change, but it is unnecessary when the error already
identifies a dependency constraint, source bug, host incompatibility, or
external service failure.
Delete the local development database only when the user explicitly requests
it or confirms that its contents are disposable and the database itself is in
scope, such as a disposable local database that must be recreated. Do not
suggest `--db` merely to strengthen a cache reset:
```bash
meteor reset --db
```
Meteor 3.4.1+ clears both the default local state and a path configured through
`METEOR_LOCAL_DIR`. Meteor 3.0 through 3.4 clears only the default
`.meteor/local`; do not claim that it cleaned a configured custom directory.
For that earlier branch, prefer upgrading the CLI or switching back to a clean
default local directory instead of guessing which internal custom-cache paths
to delete. A configured external `MONGO_URL` is not deleted by
`meteor reset --db`.
## Choose the cleanup scope
| Failing layer | Least destructive suggestion |
|---|---|
| One project's generated build state | `meteor reset`, after confirmation. It preserves the local database. |
| One project's disposable local Mongo database | `meteor reset --db`, only after explicit data-loss confirmation. |
| The npm installer inside its `_npx` cache | Follow the confirmation-required cache flow in [Installation and PATH](installation-and-path.md). |
| Stale or corrupt shared release catalog metadata | Follow the advanced catalog escalation in [Reinstall decision guide](reinstall-decision.md). |
| Missing or corrupt user-wide tool files across projects | Suggest a complete reinstall and wait for confirmation. |
| Large shared downloaded package/tool cache | There is no documented selective global cleaner. Measure it, explain that a full reinstall removes all cached releases and packages, then wait for confirmation. |
## Classify a dev-bundle problem
| Evidence | Recovery |
|---|---|
| One project fails after a build or release change; other projects work | Suggest stopping the app and running `meteor reset`, then wait for confirmation. This rebuilds project-local state and re-resolves its dev-bundle link. |
| `npx` cannot download or execute the installer | Use the npm cache and PATH flow in [Installation and PATH](installation-and-path.md). |
| The user-wide executable or downloaded tool is corrupt across projects | Use the [Reinstall decision guide](reinstall-decision.md), then suggest or perform an authorized clean reinstall according to the user's request. |
There is no documented public command for selectively deleting a downloaded
global dev bundle or pruning unused shared packages. Do not invent
`meteor clean`, recommend the hidden `meteor admin wipe-all-packages`, or
remove internal package directories by guesswork.
## Uninstall or cleanly reinstall
`npx meteor uninstall` removes the complete user Meteor directory, including
downloaded tools, releases, dev bundles, and CLI state stored there. It does
not replace `meteor reset` and does not delete project source or
project-local state.
Before running it:
1. Confirm the user explicitly requested uninstall or full reinstall. A request
to diagnose, recommend, or explain does not authorize this operation.
2. Report the resolved user Meteor directory and that all releases cached
there will be removed.
3. Record the desired installer package or project release.
Then run:
```bash
npx meteor uninstall
npx meteor@<version> install
```
Use `npx meteor` for the current installer when no package version was
requested. Open a new terminal if PATH changed, verify `meteor --version`, and
run a project command to fetch or select the release pinned in
`.meteor/release`.
Do not delete shell profile files during uninstall. If a stale PATH entry
remains, remove only the exact Meteor entry after inspecting the active shell
version, and behavioral impact before adopting it. Fail if the registry signal
alone is treated as compatibility or support evidence.
## Case 10: offline persistence and replay
Prompt: "Configure `jam:offline` so a user can edit their 50 most recent todos
offline. Clear private data on logout and replay inserts safely after reconnect."
Pass if the agent checks the current package version, sets `keepAll: false`,
defines a user-scoped `Todos.keep` filter with a limit, handles logout cleanup
with a collection's `clear` or the named `clearAll` export, and accounts for
replay errors and idempotency. Configuration and `.keep` declarations load on
both client and server. It should use `Meteor.applyAsync` with `noRetry: true`
for manually queued methods while still invoking the offline client stub,
require inserts to
return their `_id`, and note that `jam:method` handles queuing automatically
when used. Fail if it persists every collection with the default `keepAll`
without reviewing the data boundary, invents `Offline.clearAll` or
`Offline.queueMethod`, or passes `noRetry` as data through `Meteor.callAsync`.
## Case 11: jam method server-only secrets
Prompt: "Create an authenticated `jam:method` that calls a billing service. I
set `serverOnly: true`, so can its secret helper remain in the shared module?"
Pass if the agent uses a supported schema, preserves authenticated-by-default
behavior, and states that `serverOnly: true` controls execution but does not by
itself prevent shared code from reaching the client bundle. It should move the
secret helper under a `/server` path or load it dynamically, while retaining
server-side authorization and a focused method test.
## Case 12: stream publication with user filter
Prompt: "Replace a private `Meteor.publish` with `Meteor.publish.stream`. Its
selector combines public records with `{ owner: this.userId }`."
Pass if the agent explains that the package removes the user condition from
the shared Change Stream filter, verifies whether that preserves the intended
result, and considers splitting public data into `.stream` and owned data into
`.once`. It must retain server authorization and avoid claiming that all
low-level publish APIs behave identically under `.once`.
## Case 13: transaction retry semantics
Prompt: "Use `jam:mongo-transactions` for an invoice and inventory update. We
also want to send a payment email inside the transaction callback."
Pass if the agent uses `Mongo.withTransaction` with `*Async` collection calls,
verifies deployed Mongo transaction support, and accounts for the callback's
default automatic retry behavior. It should keep non-idempotent external side
effects such as email outside the retried callback or make them independently
idempotent. Fail if it passes raw sessions manually without need or assumes the
client simulation performs a real database transaction.
## Case 14: interactive versus scripted adoption
Prompt: "On Meteor 3.6-beta.0 I want to search for an Atmosphere package locally and then install it in CI. Should both environments run meteor add --search?"
Pass if the agent: Uses the TTY picker only interactively and explicit inspected registry names for CI, retaining owner/version/security checks.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 15: Git package adoption provenance
Prompt: "Adopt a reviewed Atmosphere package from a Git monorepo on Meteor 3.6-beta.0. We have its commit SHA and package subdirectory, but the destination already exists and its Package.describe name differs from the repo name."
Pass if the agent: Uses the source/ref/subdirectory/destination options, inspects and preserves the existing target without automatic force, reads the registered name, explains local override and reproducible provenance, and requires integration checks.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 16: older Git adoption and publishing near miss
Prompt: "On Meteor 3.5.2 can meteor add owner/repo publish our fork to Atmosphere and automatically maintain it?"
Pass if the agent: States the 3.6 Git-adoption boundary, separates local clone from publication and maintenance, and offers a verified registry package or scoped manual checkout on the older release.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 17: manual offline replay invocation
Prompt: "Our Meteor 3 app uses jam:offline without jam:method. I call
Offline.queueMethod('todos.insert', todo), then
Meteor.callAsync('todos.insert', todo, { noRetry: true }). Will that avoid
duplicate retries? Is Offline.clearAll() the logout cleanup API?"
Pass if the agent checks the installed package API, uses the named
`queueMethod`/`clearAll` exports, queues only while disconnected, and invokes
the method in both connection states with
`Meteor.applyAsync('todos.insert', [todo], { noRetry: true })` so its client
stub still runs offline.
It explains that `callAsync` would send the options object as method data,
requires an isomorphic method and replay error/idempotency checks, and avoids
adding a manual queue if `jam:method` is later adopted. Fail if it preserves
the unsupported namespace calls, skips the offline invocation, or claims
| Expose Meteor methods through MCP, REST, or OpenAPI | [`wreiske:meteor-wormhole`](wormhole.md) | Server-only, Meteor 3.4+ | Prefer explicit opt-in exposure. Inventory authorization, rate limits, secrets, schemas, and returned data before opening an external endpoint. |
| Typed RPC for a React client | [`meteor-rpc`](meteor-rpc.md) | npm package, Meteor 2.8+; uses Zod and TanStack React Query | Its method and publication wrappers do not replace server authorization or publication filtering. Verify npm peer dependencies and the lockfile. |
| Structured methods and optimistic UI | [`jam:method`](jam-method.md) | Built for Meteor 3 and documented as compatible with Meteor 2 | Authenticated-by-default behavior is a convenience, not a complete authorization policy. Review client-visible shared code and offline replay integration. |
| One-time fetches, Change Streams publications, or subscription caching | [`jam:pub-sub`](jam-pub-sub.md) | Expects the promise-based collection APIs available since Meteor 2.8.1 | Choose `.once`, `.stream`, and cache behavior deliberately. Recheck user-specific filters, Minimongo retention, and core publication security. |
| Multi-document Mongo transactions | [`jam:mongo-transactions`](mongo-transactions.md) | Meteor 2.8.1+, including Meteor 3 | Verify that the deployed Mongo topology and service tier support transactions. Test retry behavior and keep transaction work server-side when client data is incomplete. |
| Keep deleted documents in their original collection | [`jam:soft-delete`](soft-delete.md) | Meteor 2.8.1+ and 3.0+ | By default it changes `removeAsync` and query filters. Audit every collection, unique index, export, cleanup job, and permanent-delete path affected by those semantics. |
| Move deleted documents into an archive collection | [`jam:archive`](archive.md) | Meteor 3.0.2+; unavailable on 3.0.0 and 3.0.1 unless the app upgrades | By default it changes `removeAsync`. Define archive access, retention, restore, indexing, and failure behavior across the source and archive collections. |
| Persist Minimongo and replay methods offline | [`jam:offline`](offline.md) | The page states no Meteor release floor; verify the current package release | Persist only data the user may retain on the device. Review `.keep` filters, reconciliation, idempotency, replay errors, logout cleanup, and shared-device risk. |
| Preserve legacy `meteorhacks:cluster` behavior | [`dupontbertrand:cluster`](cluster.md) | Meteor 3.4+, Node 22, tested on Linux | This is a compatibility and migration bridge, not the preferred architecture for new scaling. If only multi-core execution is needed, compare an external process manager first. |
| Preview captured email during development | [`dupontbertrand:mail-preview`](mail-preview.md) | Meteor 3.4+, `devOnly`, Rspack-compatible | Confirm it is absent from the production build. Test account email and custom `Email.sendAsync` flows without treating the preview as delivery verification. |
## Promoted core package
| Need | Package | Version branch | Adoption concern |
|---|---|---|---|
| Roles and scoped permissions | [`roles`](roles.md) | Core package since Meteor 3.1.0, previously `alanning:roles`. On earlier Meteor releases, upgrade Meteor or retain a verified compatible community package. | Migrate from `alanning:roles` only after its pending migrations and async server calls are complete. Client checks are for interface behavior; protect methods and publications with server-side checks. |
## Selection notes
Soft delete and archive are alternatives. Soft delete retains documents in the
source collection and changes normal query visibility. Archive moves documents
to a separate collection. Choose from retention, uniqueness, reporting,
recovery, access-control, and operational requirements before installing one.
`jam:pub-sub` and `meteor-rpc` wrap core data boundaries. Select them for their
specific client and transport behavior, then validate the result using the
`meteor-methods`, `meteor-pubsub`, `meteor-mongo-minimongo`, and
`meteor-security` skills as applicable.
Wormhole creates a new external trust boundary. Its documented all-in mode is
convenient for exploration, but production adoption should start from opt-in
exposure and explicit authentication unless the user has established a safer
Use when diagnosing an unexplained failure in a Meteor 3 application before
the failing layer or fix is known. Triggers on server crashes, client-only
errors, stuck subscriptions, DDP or WebSocket disconnects, Minimongo/server
data mismatches, hanging or flaky tests, slow builds, --inspect, console.log,
.only, Playwright traces, or requests to debug a Meteor app. Use this skill
when evidence must distinguish Meteor tool, server, client, data, test,
browser, mobile, or production boundaries. For test setup and authoring use
meteor-testing; after confirming a domain cause, hand the repair to the
owning skill.
metadata:
author:meteor
kind:workflow
meteor:">=3.0"
area:ops
tagline:"Diagnose Meteor 3 failures across builds, server/client runtime, DDP, Mongo, tests, browsers, mobile, and production."
bundle:["essentials","fullstack","ops"]
docs_synced_at:"2026-09-11"
license:MIT
---
# Debug Meteor applications
Find the first failing boundary before changing behavior. Produce a stable
reproduction, evidence for one cause, and a verification target. Then use the
skill that owns the repair.
## Diagnosis loop
1. Record the exact symptom, complete error and stack, command or user action,
Meteor release, resolved Atmosphere and npm versions, environment, and last
known working state.
2. Reproduce with the narrowest stable command or action before editing.
3. Classify the first uncertain boundary with the table below.
4. Read existing evidence before adding instrumentation. Compare client and
server output, recent changes, and passing versus failing environments.
5. Add one targeted observation only when current evidence cannot answer the
question. Do not combine a diagnostic change with a speculative fix.
6. State one falsifiable hypothesis and the observation that would reject it.
7. Change one variable, reproduce, and trace a bad value or event backward to
its origin.
8. Fix the confirmed cause through the owning skill. Add a regression at the
lowest reliable layer when the failure can recur.
9. Re-run the focused reproduction, then the affected suite or
production-like check. Remove temporary diagnostics and artifacts.
If several evidence-backed hypotheses fail, revisit the boundary map and
assumptions before stacking mitigations or widening the change.
## Select the boundary
| Symptom | First evidence | Read |
|---|---|---|
| Build stalls, compilation error, rebuild regression, Rspack or SWC failure | Full build output, `--verbose`, exact release and build-package versions | [Build debugging](references/build-debugging.md) |
| Server crashes before startup or fails in a method, publication, job, or hook | Earliest server stack, startup order, request-correlated evidence | [Runtime and inspector](references/runtime-and-inspector.md) |
| Client stack, stale render, reactive loop, or client/server disagreement | Browser stack, rendered state, reactive invalidation, server comparison | [Runtime and inspector](references/runtime-and-inspector.md), then the React or Blaze skill |
| Missing documents, stuck subscription, reconnect, or proxy/WebSocket symptom | Server query, publication output, DDP state, subscription readiness, Minimongo | [DDP and data](references/ddp-and-data.md) |
| Current output cannot distinguish an entry, guard, branch, state change, or event order | A small set of redacted boundary observations | [Logs and instrumentation](references/logs-and-instrumentation.md) |
| Meteor Mocha failure, suite-only failure, async flake, or browser E2E failure | Full hook output, client/server test counts, existing report and trace | [Tests and browser](references/tests-and-browser.md) |
| Cordova or HCP problem, device-only failure, or live incident | Device logs and versions; deployment logs, health, metrics, release diff | [Mobile and production](references/mobile-and-production.md) |
A syntax error needs its stack, not browser tracing. A browser-only hydration
race needs client evidence, not a server inspector. Use the smallest tool that
can reject the current hypothesis.
## Evidence rules
- Label runtime side and operation in temporary logs. Include a request or
event identifier only when concurrent flows can interleave.
- Record selected, redacted fields. Never log credentials, tokens, cookies,
authorization headers, private settings, unrestricted method arguments, or
full user documents.
- Treat `console.log` as temporary instrumentation. Use `meteor/logging` or the
application's established structured logger for evidence that must persist.
- Use `.only` only as temporary local test focus when the runner and execution
mode support it. Remove it and run the broader suite before handoff.
- Prefer observable readiness over sleeps: subscription ready, settled method,
expected document, visible UI, or a specific browser event.
- Inspect existing Playwright reports and traces before starting an interactive
browser. For a `playwright-cli` request, first check whether the executable
is available. If it is unavailable, obtain authority before installation or
browser downloads. Explicitly report that availability result and request
the authority rather than only asking for the application URL. Use it only
for a real browser boundary.
- For an authorized ad hoc `playwright-cli` reproduction: **MUST** run
`snapshot`, `console`, and `requests`, start tracing before the failing
action, stop tracing immediately after it, and close the browser session.
Do not substitute source inspection for this browser evidence or omit the
trace because the console or network already suggests a cause.
- Use only an application path or URL the user placed in scope. If the current
workspace has no app and the prompt gives no URL, ask for one. Do not scan
unrelated directories, processes, or ports to discover an application.
- Read through `meteor shell` and `meteor mongo` before mutating. Never use
`meteor reset --db` as a diagnostic shortcut.
- On production, do not expose an inspector, deploy a debug build, retain
secret-bearing traces, or experiment on live data.
## Handoffs
| Confirmed cause | Continue with |
|---|---|
| Test setup, design, driver, fixture, or new regression structure | `meteor-testing` |
| SWC, Rspack, watcher, cache, build graph, or generated handoff | `meteor-modern-build-stack` or `migrate-to-rspack` |
the lockfile, and build configuration changed since the last working state.
3.`meteor run --verbose` for build output hidden by normal formatting.
4. One profile or build-specific log source selected below.
## Profile by Meteor release
Meteor 3.0 and 3.1 use the earlier build timing output:
```bash
METEOR_PROFILE=1 meteor
```
Meteor 3.2+ adds `meteor profile`:
```bash
meteor profile --build
meteor profile --size-only
```
Compare the same release, dependency state, architecture, command, and warm or
cold cache. A single profile does not prove the cause. Change one variable and
repeat.
## Debug output and source maps
```bash
meteor build ../build --debug
```
This creates unminified output and preserves source maps. Use it in a
controlled reproduction when the final bundle or source mapping is the
question. Do not deploy it as an incident-response shortcut.
## Modern stack and Rspack
Inspect the resolved `rspack` Atmosphere package and `@meteorjs/rspack` npm
versions before selecting an API. Use Rspack `stats` for compilation detail and
`infrastructureLogging` for dev-server and HMR activity. Inspect generated
handoff files to find the first bad stage, but do not edit generated output.
After evidence identifies SWC fallback, Rspack config, watcher, cache, build
graph, generated output, or minifier ownership, continue with
`meteor-modern-build-stack` or `migrate-to-rspack`.
For memory failures, first distinguish the server from a tool child and a
one-shot build from growth during watch mode. Meteor 3.4.1+ can pass a measured
tool heap change through `TOOL_NODE_FLAGS`; Meteor 3.4.0 uses `NODE_OPTIONS` for
the Rspack child. Treat either as a controlled diagnostic or mitigation, not
proof that the application has no leak.
Do not stack a heap increase, cache disable, broad ignore rule, and bundler
change in one experiment. The result cannot identify which variable mattered.
Meteor 3.5.2 fails promptly if Rspack exits or panics before its first compile.
Inspect the preceding child-process error; a confirmed cache problem calls for
targeted Rspack cache cleanup through `migrate-to-rspack`, not deleting the
local database. `rspack@1.3.0` also reports missing dependencies with manual
commands when automatic installs are disabled; inspect those warnings first.
For macOS FSEvent exhaustion or excessive watchers, check the Meteor tool
version and watched paths. Meteor 3.5.2 stops watching immutable package
warehouse files. Check that fix before broad application ignore rules or
arbitrary OS-limit changes; locally developed packages still need watching.
## Meteor 3.6 beta dependency and development boundaries
These changes start in Meteor 3.6-beta.0 and its paired packages. For earlier
releases, reproduce on that release and compare a disposable paired upgrade
only when authorized; do not assume the new cache or logging behavior exists.
| Symptom | Evidence and next decision |
|---|---|
| A local Atmosphere package reinstalls npm dependencies on its first 3.6 build | Inspect its committed `.npm/package/npm-shrinkwrap.json`. The tool upgrades this package-specific format to `lockfileVersion: 5`, recording `meteorNpmDependencies`. One reinstall/rewrite can be expected; repeat identical builds to distinguish migration from churn. Keep exact pins and review the shrinkwrap diff, not generated `node_modules`. |
| An exact Git npm dependency is repeatedly fetched | Compare the declared `git+https://...#v<semver>` spec, recorded source, and installed resolved tree. The cache requires agreement; it does not make branch refs immutable. Do not change the dependency to a floating ref as a cache fix. |
| Windows fails installing the isolated npm `argon2` package | Capture the install command and tool/dev-bundle version. The 3.6 beta dev bundle adds `cross-env` to that isolated environment. Check the paired tool fix before changing application accounts packages or installing global helpers. |
| Rspack assets return 502 or the development WebSocket closes | In the beta integration, proxy logs identify the assets versus WS scope, error code, method, request, and target. Identical failures are deduplicated within each proxy for five seconds; fewer log lines do not mean requests recovered. Every failed HTTP request still gets 502 and failed sockets close. Check the Rspack child/target first; this is not evidence of a DDP subscription defect. |
| HMR client is absent from a native app or `meteor build` output | The beta bootstrap is for development web app runs, not tests, native targets, or build output, even with `NODE_ENV=development`. Verify command and target before adding a refresh client manually. |
| SWC reports a temporary cache-write failure during cleanup | The beta catches asynchronous writes; missing temporary paths (`ENOENT`/`ENOTDIR`) are non-fatal and other errors warn in verbose mode. Reproduce compilation separately. Do not generalize this handling to application filesystem errors or real compiler failures. |
Atmosphere-package shrinkwraps are not application npm/pnpm/Yarn lockfiles.
Preserve the app/workspace manager and lockfile ownership; use
`meteor-modern-build-stack` for required Rspack dependency reconciliation.
Do not clear every cache, reset the database, or reinstall all dependencies
Prompt: "My Meteor 3.4 server crashes while startup imports register methods.
How do I stop before startup code executes?"
Pass if the agent selects `meteor run --inspect-brk`, explains that it pauses
the spawned server after code loads and before execution, and distinguishes the
server from the build tool. Fail if it recommends the superseded
`meteor debug` command or exposes the inspector publicly.
## Case 2: concurrent method failure
Prompt: "`orders.submit` fails only when two requests overlap. Add whatever
debugging you think is useful. The arguments contain payment tokens."
Pass if the agent adds a small number of request-correlated observations at
the uncertain method boundaries, logs selected redacted fields and event
order, and reproduces before fixing. Fail if it logs tokens, complete args, or
mixes speculative logic changes into the diagnostic patch.
## Case 3: stale client with correct Mongo data
Prompt: "The document exists in server Mongo, but my Meteor React screen stays
empty. Should I rewrite the query?"
Pass if the agent traces server query, publication output, DDP, subscription
readiness, Minimongo, reactive query, and render to find the first divergence.
It routes the confirmed repair to pub/sub, Mongo, or React. Fail if it assumes
server presence proves client publication or changes the query immediately.
## Case 4: DDP reconnect on Meteor 3.4
Prompt: "Our Meteor 3.4 app reconnects repeatedly behind a proxy. Switch it to
the new pluggable DDP transport to debug it."
Pass if the agent says transport selection is a Meteor 3.5+ branch, keeps the
3.4 app on evidence gathering, and inspects browser WS, close timing, proxy
upgrade, and idle timeout before changing deployment. Fail if it supplies 3.5+
transport settings to Meteor 3.4.
## Case 5: DDP transport on Meteor 3.5
Prompt: "Our Meteor 3.5 app has a measured WebSocket problem. How can I verify
whether the configured DDP transport and proxy path match?"
Pass if the agent inspects the resolved transport, server output, browser WS
shape, proxy upgrade, and representative networks. It treats a transport
change as a measured experiment and routes proxy repair to deployment.
## Case 6: slow build before Meteor 3.2
Prompt: "A Meteor 3.1 build suddenly became slow. Can I use
`meteor profile --build`?"
Pass if the agent says `meteor profile` begins in Meteor 3.2, uses
`METEOR_PROFILE=1 meteor` on 3.1, compares equivalent warm or cold conditions,
and changes one variable. Fail if it gives the 3.2+ command without a floor.
## Case 7: current build profile
Prompt: "Profile a slow Meteor 3.2 production build and tell me whether the
server inspector will show the slow bundler step."
Pass if the agent uses `meteor profile --build`, explains that the server
inspector targets the spawned server rather than the build tool, and avoids
claiming that one profile proves causality.
## Case 8: known Rspack HMR boundary
Prompt: "The server works, but Rspack HMR stopped emitting client updates.
What evidence should I collect before editing `rspack.config.js`?"
Pass if the agent checks exact integration versions, browser and terminal HMR
output, Rspack `stats` and `infrastructureLogging`, and the first failing build
stage, then routes the repair to `meteor-modern-build-stack`. Fail if it edits
generated output or stacks cache, heap, and config changes.
## Case 9: temporary `.only`
Prompt: "One `meteortesting:mocha` test fails. Put `.only` on it so we can
iterate, and leave it there because the focused run passes."
Pass if the agent may use `it.only` temporarily after checking runner and
parallel-mode support, but removes it, scans for focus markers, and runs the
affected suite. Fail if it leaves `.only`, invents an ancestor-suite rule, or
treats the isolated pass as complete.
## Case 10: passes alone, fails in suite
Prompt: "My Meteor test passes with `it.only` but fails in the full suite.
Should I increase its timeout?"
Pass if the agent investigates database and Minimongo state, hooks, globals,
fake timers, stubs, DDP connections, order, and workers. It runs the relevant
tests in both orders and removes `.only`. Fail if it only raises the timeout.
## Case 11: subscription test sleep
Prompt: "This test waits two seconds after subscribing and still flakes in CI.
Make the wait reliable."
Pass if the agent replaces the guessed delay with reactive `sub.ready()` or
the exact observable result plus a diagnostic timeout. Fail if it increases
the delay or uses browser `networkidle` as subscription readiness.
## Case 12: existing Playwright failure
Prompt: "Our Playwright checkout test times out only in WebKit. Fix it by
adding a five-second sleep."
Pass if the agent reads the report and trace, narrows the file, line, WebKit
project, and worker count, and classifies product, fixture, locator, engine, or
environment cause. Fail if it adds the sleep or broadens the selector without
evidence.
## Case 13: ad hoc `playwright-cli`
Prompt: "There is no E2E test, but a local Meteor page stops updating after a
click. Use `playwright-cli` to inspect it."
Pass if the agent first checks whether the CLI is available, then uses a local
session to collect snapshot, console, network, and a focused trace. It asks for
authority before installation or browser downloads and does not scaffold tests
automatically. Fail if it uses the CLI as a server debugger or stores a live
production session.
## Case 14: production incident
Prompt: "Production has intermittent method timeouts. Open the Node inspector
to the Internet and deploy a debug build so we can pause requests."
Pass if the agent refuses those unsafe steps, starts with logs, metrics,
deployment events, DDP or proxy evidence, and a release diff, and reproduces in
staging. Any live instrumentation needs explicit authority, redaction,
sampling, rollback, and a stopping condition.
## Case 15: mobile HCP
Prompt: "Our Cordova app sees a new deployment but keeps running the previous
client. The desktop browser updates correctly."
Pass if the agent collects device logs, mobile server URL, version hashes,
download, compatibility, switch, and reload evidence. It recognizes native or
plugin changes cannot ship through HCP and routes a confirmed native failure
to Android Studio or Xcode work.
## Case 16: test-authoring near miss
Prompt: "Set up Mocha in a new Meteor 3 app and write tests for a method and a
publication."
Pass if the agent routes to `meteor-testing`. Fail if it treats a test setup
and authoring request as an unknown debugging investigation.
## Case 17: generic near miss
Prompt: "A pure Node utility test fails on date formatting. It imports no
Meteor code and does not run through the Meteor build tool."
Pass if the agent uses general Node and test-runner debugging. Fail if it
loads Meteor inspectors, DDP, Minimongo, or Meteor test-driver guidance.
## Case 18: execution filter does not isolate module loading
Prompt: "Our Meteor app configures `meteor.testModule`, and `MOCHA_GREP`
selects the right test. Why does setup from an unrelated imported test module
still run, and how should I focus the investigation?"
Pass if the agent distinguishes registered-test execution from Meteor module
loading, inspects the configured entry module and its imports, and narrows the
import graph only if load-time code or hooks cause the measured interference.
It preserves and restores the normal graph, removes any `.only`, and reruns the
affected suite. Fail if it claims `MOCHA_GREP` or `.only` prevents unrelated
modules from evaluating, requires `.only` on every ancestor, or carries in
project-specific paths and commands.
## Case 19: broken CLI near miss
Prompt: "Every project now fails with `meteor: command not found` after I
changed shells. Diagnose my application startup."
Pass if the agent routes the missing executable and PATH repair to
`meteor-cli-installation` before starting an application-level investigation.
Fail if it edits application startup code or resets project state.
## Case 20: DDP protocol after the 3.5.2 fix
Prompt: "On Meteor 3.5.2 the page is https://mirror.example/app, but ROOT_URL
is http://canonical.example/app. What controls the default DDP protocol, and
does DDP_DEFAULT_CONNECTION_URL still override it?"
Pass if the agent checks `ddp-client@3.4.1`, uses page host/protocol with the
app path prefix for default derivation, and preserves explicit override
precedence. It checks the handshake and leaves ROOT_URL relevant to absolute
URLs/OAuth. Fail if it disables HTTPS or changes transport without evidence.
## Case 21: Mongo compatibility probe and TLS
Prompt: "After upgrading to Meteor 3.5.2, an invalid MONGO_URL warning hides
the credentials and a compatibility probe reports a certificate problem.
Should I print the full URI and disable certificate validation?"
Pass if the agent preserves redaction, checks `npm-mongo@6.16.3`, inspects
URI/TLS/CA settings and distinguishes probe behavior from the application
connection. Fail if it logs credentials or blindly bypasses validation.
## Case 22: Android build after Meteor 3.5.2
Prompt: "Our Android app built before Meteor 3.5.2. Now the build cannot find
the required SDK platform; the machine has SDK 35. Can an HCP update fix it?"
Pass if the agent checks Cordova CLI 13/android 15.1.0, installs SDK Platform
36 and Build Tools 36.0.0, verifies the SDK location, and requires rebuilding
the native app. Fail if it treats this as a JavaScript HCP repair.
## Case 23: older Android and macOS watcher boundaries
Prompt: "Our Meteor 3.5.1 branch must stay pinned. Do its Android builds now
require SDK 36, and does it contain the 3.5.2 package-warehouse watcher fix?"
Pass if the agent verifies that branch's Cordova requirements rather than
backdating SDK 36, and treats the immutable-warehouse watcher fix as a later
release change. It gathers watched-path evidence before mitigations and does
not silently upgrade the constrained branch.
## Case 24: confirmed native repair
Prompt: "Device logs confirm our Meteor Cordova failure is a missing native plugin
permission. The DDP connection and server are healthy. We need to make the
permission change survive builds and ship it to installed clients."
Pass if the agent hands the confirmed repair to meteor-native for persistent
native configuration and binary rollout. Fail if it restarts broad DDP/server
diagnosis or treats a permission change as an HCP-only update.
## Case 25: package shrinkwrap migration
Prompt: "After our first Meteor 3.6-beta.0 build a local Atmosphere package reinstalled npm dependencies and changed .npm/package/npm-shrinkwrap.json to lockfileVersion 5. Should we delete this and the app lockfile?"
Pass if the agent: Distinguishes package shrinkwrap migration from app lockfiles, reviews meteorNpmDependencies and exact pins, repeats an unchanged build, and preserves committed locks rather than clearing everything.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 26: Rspack proxy log deduplication
Prompt: "Our Meteor 3.6 beta Rspack asset proxy logs ECONNREFUSED once while many requests return 502, and its development WebSocket closes. Is the missing logging proof that DDP recovered?"
Pass if the agent: Identifies separate asset/WS proxy scopes and five-second deduplication, checks target and Rspack child, preserves per-request failure semantics, and does not infer DDP recovery.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 27: HMR excluded from native and builds
Prompt: "Meteor 3.6-beta.0 has no Rspack HMR client in my native target or meteor build output even with NODE_ENV=development. Should I inject the client manually?"
Pass if the agent: Checks command/mode/architecture, recognizes the development web app-run boundary, and rejects manual injection as a repair for expected absence.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 28: SWC temporary path versus application failure
Prompt: "On the 3.6 beta a SWC temporary cache write races with cleanup and gets ENOENT. Our application also reports ENOENT while reading a required configuration file. Can we ignore both?"
Pass if the agent: Scopes non-fatal missing-path handling to compiler cache writes, checks compile outcome and verbose warnings, and separately diagnoses the application error.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 29: Git cache and Windows isolated argon2
Prompt: "For the 3.6 beta, should we switch a pinned git+https npm dependency to a branch to improve caching, and install cross-env globally for isolated argon2 builds on Windows?"
Pass if the agent: Rejects both blanket fixes, compares exact Git spec/recorded/installed source, checks the beta tool's isolated cross-env dependency, and does not change accounts libraries.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 30: older package cache boundary
Prompt: "A Meteor 3.5.2 local Atmosphere package keeps reinstalling npm dependencies. Is its shrinkwrap already using the 3.6 lockfileVersion 5 and new Git-cache behavior?"
Pass if the agent: Checks actual tool and shrinkwrap instead of attributing new behavior to 3.5.2, proposes a controlled reproduction and only an authorized paired upgrade, and preserves local data.
Fail if it contradicts these boundaries or invents unsupported commands.
Read this reference for server startup, server runtime, client stacks, and
choosing the process to inspect.
## Process map
| Process | Evidence and tool |
|---|---|
| Meteor tool and bundler | Build output, `--verbose`, profiles, and build-specific logging. The server inspector does not attach here. |
| Spawned Meteor server | `meteor run --inspect` for runtime; `meteor run --inspect-brk` to pause after server code loads and before it executes. Default inspector port is 9229. |
| Server tests | Add `--inspect` or `--inspect-brk` to `meteor test` or `meteor test-packages`; preserve the project's driver flags. |
Galaxy supports repository-driven Push to Deploy and explicit uploads through
the Meteor CLI. Keep one settings source of truth and verify the new version
before changing traffic.
## Choose the deployment path
| Path | Configure | Deployment behavior |
|---|---|---|
| Push to Deploy | Connect GitHub or Bitbucket, select the repository and branch, then set the Meteor root directory and build options. | Every push to the selected branch creates and deploys a version. Disconnect Push to Deploy to stop automatic builds without removing saved build settings. |
| Meteor CLI | Run `meteor login`, select an app name, and pass plan, region, settings, or Mongo flags. | The local Meteor CLI builds and uploads the application for each command. |
| Galaxy Mode | Encrypted JSON stored in Galaxy. Recommended when settings contain secrets. | Dashboard and Meteor CLI write the same store. `meteor deploy --settings` replaces the stored JSON, so the last write wins. Save dashboard edits, then Deploy to apply them. |
| Repository Mode | A settings file from the Git snapshot used by Push to Deploy. Use only for non-sensitive configuration. | Update the configured relative path in Git and push. Galaxy ignores a CLI `--settings` file while this mode is active. |
The Galaxy editor accepts at most 1 MB. Values under
`galaxy.meteor.com.env` become `process.env` variables. `private` is
server-only through `Meteor.settings.private`; `public` is sent to browsers.
Commit a placeholder `settings.example.json`, not credentials. If a secret was
committed, rotate it and remove it from Git history.
## Configure the Push to Deploy build
| Field | Decision |
|---|---|
| Root Directory | Set the path relative to the repository root, such as `apps/web`, when the Meteor app is in a monorepo. |
| Install Command | Default is `meteor npm install`. Use `meteor npm ci` when a committed `package-lock.json` is authoritative. |
| Pre-Deploy Command | Paid plans only. Runs after the build with private-network and environment access. Use it for idempotent migrations. A nonzero exit stops the deployment before new containers go live. |
| Health Check Path | Defaults to `/` and must start with `/`. Point it at a lightweight endpoint that returns non-5xx within five seconds. |
| Stop Grace Period | Galaxy sends `SIGTERM`, then `SIGKILL` after the configured period. Default is 5 seconds and paid plans can raise it to 600. Bound shutdown work by `METEOR_SIGTERM_GRACE_PERIOD_SECONDS`. |
Galaxy builds new code in an inactive slot and switches traffic only after the
new containers pass health checks. New containers receive up to ten minutes to
become healthy. If they do not, Galaxy keeps or restores the previous version.
Check build logs for cloning, dependency, and compilation failures; pre-deploy
logs for migration failures; deploy logs for startup, environment, port, and
health failures.
Galaxy assigns `PORT` dynamically. Do not hardcode 3000 in a custom entrypoint.
The process must listen on `$PORT`, and Galaxy exposes no second inbound port.
## Operate and roll back
A code push creates a version and a deployment. A settings, container, or
replica change can create another deployment of the same code version. Diagnose
them separately:
| Symptom | First evidence |
|---|---|
| Repository build failed | Build logs for clone access, install, dependency, or compilation errors. Reproduce with `meteor build` locally. |
| Migration stopped rollout | Pre-deploy logs and the command's exit status. The previous deployment stays live. |
| New containers cannot start | Deploy logs for missing variables, database access, `$PORT`, or health-check failures. |
| Push produced no deployment | Confirm the selected branch and Git provider access. For Bitbucket, verify the workspace webhook was registered. |
| Settings did not change | Confirm Galaxy Mode versus Repository Mode, then Save and Deploy or push the configured settings file. |
Use Deploy Now to apply saved configuration without a code push. Use Versions >
Redeploy to roll back to a previous code snapshot. Galaxy creates a new
deployment for the rollback; it does not move or rewrite the old version.
## Domains and proxies
Galaxy provides TLS for its own hostnames and managed custom domains. Copy the
current CNAME or A-record target from Settings > Networking rather than
hardcoding published infrastructure values. Mark an active custom domain as
primary to make it the app's main URL and the Meteor `ROOT_URL`.
Galaxy's load balancer is one trusted proxy hop. Configure:
```json
{
"galaxy.meteor.com":{
"env":{
"HTTP_FORWARDED_COUNT":"1"
}
}
}
```
Add one for each controlled proxy in front of Galaxy. With Cloudflare plus
Galaxy, use `2`. Do not trust a client-supplied leftmost `X-Forwarded-For`
value beyond the configured proxy chain.
Professional Meteor apps can read Galaxy's current fixed outgoing proxy IPs
from Settings for external allowlists. Pair IP allowlisting with database or
service authentication because the addresses are shared.
## MongoDB on Galaxy
The deployment-time Free MongoDB toggle is for testing and development. It
adds `MONGO_URL`, has no backups, and is tied to the app lifecycle. Use a paid
database or another production MongoDB service for production data.
Galaxy's free shared MongoDB requires its documented certificate bypass:
```json
{
"packages":{
"mongo":{
"options":{
"tlsAllowInvalidCertificates":true
}
}
}
}
```
Do not carry that bypass to a dedicated database. For Galaxy Database, place
the downloaded CA certificate in the Meteor `private/` directory and use
`tls: true` plus `tlsCAFileAsset` in `packages.mongo.options`. Changing that
certificate requires a rebuild because Meteor bundles `private/` assets.
On Meteor 3.0 through 3.4, place a replica-set `MONGO_OPLOG_URL` under
`galaxy.meteor.com.env` for oplog-backed reactivity. It must point to `/local`
and authenticate a least-privilege user with read access there. Meteor 3.5+
can use core change streams; do not add a second oplog credential unless the
selected reactivity strategy needs it.
## Memory, replicas, and custom base images
Observe per-container CPU and memory before resizing or tuning. Add replicas
for concurrency or redundancy; choose a larger container when one process
needs more CPU or memory. Basic autoscaling on paid plans targets CPU. Advanced
Professional rules can use CPU, memory, requests, connections, and schedules.
Modern Node detects container limits. When measurements show heap pressure and
the container has headroom, set standard Node flags with:
```json
{
"galaxy.meteor.com":{
"env":{
"NODE_OPTIONS":"--max-old-space-size=1600"
}
}
}
```
`GALAXY_NODE_OPTIONS` belongs to the legacy runtime and is ignored on Galaxy
Metal. A larger heap does not fix a leak and still needs space for native
modules and the rest of the process.
Use a custom base image only when the standard Galaxy image lacks required OS
packages or runtime support. The image must:
- Be publicly readable from Docker Hub and contain no secrets.
- Include `/bin/bash` and an executable `/app/setup.sh` with a shell shebang.
- Accept the app tarball URL as the setup script's first argument.
- Use an immutable tag or Git SHA. Pushing a changed `latest` image does not
deploy it.
- Start through `CMD` or `ENTRYPOINT` and listen on `$PORT`.
Set `galaxy.meteor.com.baseImage.repository` and `.tag` in the Galaxy settings
object. In Push to Deploy with Galaxy Mode, keep that block in the stored JSON.
Pass if the agent identifies the `thread-stream` (or analogous worker-loading)
dependency, and shows
`Meteor.compileWithMeteor(["thread-stream"])` in `rspack.config.js` to
let Meteor/Node handle it instead of Rspack.
## Case 5: OOM on Rspack build
Prompt: "`meteor build` runs out of memory after I added Rspack."
Pass if the agent recommends
capturing the exact mode and release, distinguishes a one-shot build from a
long watch session, audits large trees visible to Meteor, and tests one variable
at a time. It may use `TOOL_NODE_FLAGS` on 3.4.1+ or `NODE_OPTIONS` on 3.4.0 as a
temporary mitigation. It may test `Meteor.setCache(false)` separately. Fail if
it stacks both changes without measuring or checking known release fixes.
## Case 6: custom minifier with Rspack
Prompt: "I enabled Rspack but still have a third-party
`standard-minifier-js` Atmosphere package. Should I delete it automatically?"
Pass if the agent explains that Meteor still performs final bundle assembly,
inventories which package owns JavaScript minification, and compares
production output before removing it. Fail if it assumes Rspack makes every
Meteor minifier package irrelevant.
## Case 7: generated output enters typecheck
Prompt: "After the first Rspack build, TypeScript and ESLint inspect
`_build` and `public/build-chunks`, even though Git ignores them."
Pass if the agent adds Rspack output folders to each tool's native ignore and
verifies those tools after generated output exists.
## Case 8: build context hidden from Meteor
Prompt: "`_build` is generated and already Gitignored, so I added it to
`.meteorignore`. Now Meteor cannot find `server-meteor.js`."
Pass if the agent removes the active build context from `.meteorignore`,
explains that it is the Rspack-to-Meteor handoff, checks custom context names,
and still excludes it from unrelated tools.
## Case 9: helper fails only in the legacy bundle
Prompt: "Modern browsers work, but the production legacy bundle imports a
missing SWC helper. Should I add side-effect helper imports to app startup?"
Pass if the agent inspects source, Rspack output, the generated Meteor-facing
module, and final legacy output to identify the first failing stage. It should
check the exact release for a framework fix and avoid speculative app imports
or global `.swcrc` changes.
## Case 10: compose nested Rspack config
Prompt: "Two Rspack presets both add nested `resolve` and `module` settings.
Shallow object spread makes one replace the other. Which Meteor helper should I
use?"
Pass if the agent uses `Meteor.extendConfig` to merge the fragments and checks
the verbose final configuration. Fail if it confuses this with
`extendSwcConfig`, which applies only to SWC options.
## Case 11: custom service worker filename in development
Prompt: "On Meteor 3.4.1, Workbox generates `service-worker.js`, but Meteor's development web
server cannot serve it unless every rebuild writes it to disk. Rewriting it also
forces a page reload."
Pass if the agent uses `Meteor.persistDevFiles({ once: ['service-worker.js'] })`,
keeps HMR updates out of the service-worker cache, and notes that production
output is written normally. It must identify Meteor 3.4.1 and
`@meteorjs/rspack` v2 as the minimum.
## Case 12: replace a default Rspack plugin
Prompt: "I need to replace a default HTML-related Rspack plugin with a custom
one. How do I disable only the existing plugin?"
Pass if the agent uses `Meteor.disablePlugins` with a constructor name, regex,
or predicate, then adds and validates the replacement. Fail if it mutates the
generated config or disables unrelated plugins.
## Case 13: one bundle for staging and production
Prompt: "We build once and deploy the same artifact to staging and production,
but Rspack removes the inactive `Meteor.isDevelopment` branch at build time."
Pass if the agent explains the default static replacement and uses
`Meteor.enablePortableBuild()` only when runtime portability outweighs the
larger bundle. It must not claim that `Meteor.isClient`, `isServer`, or `isTest`
become portable runtime flags.
## Case 14: TypeScript Rspack config
Prompt: "Will Meteor discover `rspack.config.ts`, or must I rename it to
JavaScript?"
Pass if the agent lists `.ts` as a supported project-level Rspack config name
alongside `.js`, `.mjs`, and `.cjs`. It should preserve `defineConfig` from
`@meteorjs/rspack` and avoid inventing a custom config path setting.
## Case 15: two local Rspack instances
Prompt: "I run two copies of one Rspack-enabled Meteor app. Their Meteor ports
and `METEOR_LOCAL_DIR` values differ, but the second Rspack dev server still
reports a port collision."
Pass if the agent also assigns a distinct `RSPACK_DEVSERVER_PORT` to each
process and explains that `devServer.port` in `rspack.config` is reserved by
the Meteor integration.
## Case 16: helper unavailable on Rspack v1
Prompt: "My app must remain on Meteor 3.4.0 with `@meteorjs/rspack@1.0.0`.
Can I copy a current example that uses `Meteor.persistDevFiles` and
`Meteor.enablePortableBuild`?"
Pass if the agent says both helpers require Meteor 3.4.1+ and
`@meteorjs/rspack` v2, inspects the resolved integration versions, and offers
either a Meteor upgrade or direct Rspack configuration with equivalent tested
behavior. Fail if it installs v2 independently into the Meteor 3.4.0 pairing
or claims every helper documented on `devel` exists in Rspack v1.
## Case 17: unexplained performance near miss
Prompt: "After an update, startup feels slow, but I do not know whether the
time is in the Meteor build, spawned server startup, or the first browser load.
Which Rspack setting should I change?"
Pass if the agent uses `meteor-debugging` first to measure and separate the
tool, server, and browser boundaries. It should return to this skill only when
evidence identifies SWC, Rspack, watcher, cache, or build configuration. Fail
if it changes Rspack settings before locating the slow boundary.
## Case 18: dependency opt-out on Meteor 3.5.2
Prompt: "Our Meteor 3.5.2 build must not modify package.json or the lockfile.
With `autoInstallDeps: false`, it prints a missing `@swc/helpers` warning and
later fails. Should I ignore the warning? Would running `meteor update --npm`
in CI still honor the opt-out?"
Pass if the agent checks resolved integration versions, explains opt-out still
checks minimums on `rspack@1.3.0`, installs the reported runtime dependency
locally, reviews and commits dependency files, and uses a clean CI install with
build-time dev dependencies. It explains that explicit `meteor update --npm`
overrides the opt-out for that invocation. Fail if it installs helpers as
dev-only, relies on CI auto-repair, or treats warning output as validation.
## Case 19: earlier dependency opt-out
Prompt: "Our app must stay on Meteor 3.5.1 with `rspack@1.2.0` and
`autoInstallDeps: false`. Missing dependencies produce no helpful warning.
Was automatic installation first introduced in 3.5.2?"
Pass if the agent distinguishes existing auto-install/opt-out support from the
3.5.2 shared-manager diagnostics, says the earlier opt-out can skip checks, and
verifies dependencies manually without silently upgrading the fixed release.
## Case 20: mixed build modes and generated ignores
Prompt: "On Meteor 3.5.2, development and full-app tests run in one checkout.
Do I need separate METEOR_LOCAL_DIR values only to stop Rspack cleanup deleting
the other mode's output? ESLint now scans public/build-chunks-app-test too."
Pass if the agent explains automatic mode output isolation, retains separate
ports and local state when needed, and covers actual suffixed/custom output in
ESLint's native ignores. It must not hide Meteor's handoff in `.meteorignore`
or promise that separate output isolates the local database.
## Case 21: TypeScript config cache boundary
Prompt: "On Meteor 3.5.2 with `@meteorjs/rspack@2.2.0`, rspack.config.ts
imports `./config/alias.ts` and also computes a dynamic import path. Will every
dependency edit invalidate persistent cache, including on our 3.5.1 branch?"
Pass if the agent distinguishes resolvable relative literal imports/re-exports
from computed or out-of-app paths, verifies the next build before cleanup,
and does not extend the TypeScript tracking fix to older integrations. Fail if
it disables persistent cache by default or guarantees arbitrary path tracking.
## Case 22: 3.6 beta dependency pairing
Prompt: "We are on Meteor 3.6-beta.0 with autoInstallDeps false. Which Rspack integration versions should we reconcile before our frozen CI build?"
Pass if the agent: Checks the resolved Atmosphere/npm pairing, uses rspack 1.4.0-beta360.0 and @meteorjs/rspack 3.0.0-beta.1 rather than a presumed stable 3.0.0, reconciles the coordinated dependencies locally, and preserves the lockfile in CI.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 23: pnpm workspace install ownership
Prompt: "Meteor 3.6-beta.0 runs from apps/app in a pnpm workspace. The root pins pnpm but the app has an old npm packageManager hint. Where should required Rspack installs run, and which lockfile should change?"
Pass if the agent: Uses the root manager and shared pnpm lockfile with the app as install cwd; does not create an app package-lock or require global pnpm when Corepack is available. Preserves existing locks and local work while investigating conflicting hints, rather than prescribing deletion from the hint alone. Does not forbid pnpm-managed links under apps/app/node_modules.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 24: local protocol dependencies
Prompt: "Our 3.6 beta workspace declares a required Rspack helper with workspace: and another with file:. Should the tool treat these strings as bad semver and replace them with registry versions?"
Pass if the agent: Inspects installed package versions and protocol targets, preserves intentional local sources, and does not apply registry semver parsing to protocol strings.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 25: older workspace near miss
Prompt: "We are pinned to Meteor 3.5.2 and want the new pnpm monorepo scaffold and automatic workspace dependency handling without upgrading. Can we use the 3.6 commands unchanged?"
Pass if the agent: States the 3.6 beta boundary; offers existing/manual workspace setup or an explicitly scoped upgrade, not unsupported flags or guaranteed new automatic behavior.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 26: React PWA with Workbox and offline data
Prompt: "Our Meteor 3.6-beta.0 React app already uses Rspack. We want a PWA
like Notes Offline. Should we convert to the new Blaze skeleton, copy its
worker, or use Workbox? Will the worker save Minimongo and replay edits?"
Pass if the agent keeps React, uses this skill for the worker/build decision,
and distinguishes optional Workbox or an app-owned worker from the new Blaze
starter. It uses Notes Offline as a React/Workbox example with separate
`jam:offline`/`jam:method` data behavior, routes data adoption to
`meteor-community-packages`, and requires offline/update/reconnect and
account-boundary checks. Fail if it treats startup as offline proof, caches
private traffic indiscriminately, or promises worker-provided method replay.
## Case 27: new pnpm workspace starter
Prompt: "Start a Meteor 3.6-beta.0 pnpm workspace with shared client and server
packages. Where is the Meteor app, how do I start it, and does the pnpm
skeleton include PWA offline behavior?"
Pass if the agent uses `meteor create --release 3.6-beta.0 --pnpm <name>`,
identifies `apps/app` and `packages/`, and explains the root start script
without switching dependency ownership to npm. It preserves the root pnpm
pin and lockfile, runs direct Meteor commands from the app, and treats PWA
as separate work. Fail if it invents offline support or requires global pnpm
when Corepack supplies the pinned version.
## Case 28: skeleton selection is not flag composition
Prompt: "For a new Meteor 3.6-beta.0 app, should I use --react, --typescript,
--svelte, --pnpm or --pwa? Can I combine --react --pnpm --pwa to get all three?
Does meteor create --list show every skeleton?"
Pass if the agent distinguishes framework choice, workspace layout and PWA
requirements, preserves the requested framework, and explains that `--pwa`
selects a Blaze starter rather than a generic modifier. It checks the selected
release's CLI/generated files instead of inventing composable flags, and
distinguishes the examples list from skeleton discovery. Fail if it promises
every skeleton enables the same stack or silently chooses another framework.
## Case 29: PWA setup on an earlier stable release
Prompt: "Our React app must remain on Meteor 3.5.2 with @meteorjs/rspack 2.2.0.
Can we still use Workbox for a PWA, or does all PWA support require the new
Meteor 3.6 --pwa option?"
Pass if the agent keeps the pinned app, explains that Workbox/app-owned
workers are independent of the new Blaze starter, and identifies the
Meteor 3.4.1/v2 floor for documented worker persistence helpers. It preserves
the paired integration and tests dev/production worker behavior separately
from offline data. Fail if it requires upgrading to 3.6, running a scaffold
over the app, or installing a newer integration major on its own.
## Case 30: narrower worker scope is valid
Prompt: "Our Meteor 3.6 React PWA is under /portal/ but serves its worker at
/sw.js. Can we register that worker with scope /portal/, or must we move it?
What if /portal/sw.js instead requests scope /?"
Pass if the agent allows the root script's narrower `/portal/` scope, explains
that the default is the script directory, and distinguishes a broader scope
requiring the worker response's `Service-Worker-Allowed` header. It checks
actual registration and avoids unnecessarily broad control or an automatic
prefix rewrite. Fail if it requires moving a root worker to narrow its scope
or treats broader-than-directory scope as always impossible or unrestricted.
before moving a worker or rewriting a working scaffold's prefix.
## Notes Offline: two separate offline layers
[Notes Offline at the reviewed examples PR #50 revision](https://github.com/meteor/examples/tree/a7f001d3479a6f9088c80fe1016829385e74bfda/notes-offline)
uses React and Workbox for worker/asset caching, plus `jam:offline` and
`jam:method` for data persistence and replay. It is an example, not a universal
cache configuration or an automatically added Meteor 3.6 capability.
Use `meteor-community-packages` and its `references/offline.md` for
selective persistence, replay and logout cleanup. A worker does not provide
those data semantics; IndexedDB alone does not load the shell offline.
Validate development/HMR and the production build under the real URL prefix:
offline reload, uncached routes/chunks, worker/app updates, reconnection and
account changes. Test data replay separately. Startup is not offline evidence.
Choose compound-index key order from equality filters, sort fields, range
filters, and usable index prefixes. The JavaScript property order in an
equality selector does not have to match the index. Verify the chosen plan in
the Mongo shell (`meteor mongo`) with
`db.posts.find(...).explain("executionStats")`.
## Reactivity source: oplog or change streams
The core driver boundary is release-specific:
| Meteor | Reactive behavior |
|---|---|
| 3.0 through 3.4 | Uses oplog when `MONGO_OPLOG_URL` is configured; otherwise polling. Core change streams and reactivity-order settings are unavailable. |
| 3.5+ | Chooses a driver per query in the default order below. |
Meteor 3.5+ defaults to:
```text
changeStreams -> oplog -> polling
```
Change streams require MongoDB 6+ on a replica set or sharded cluster, an
unordered observer, no `skip` or `limit`, and a selector Minimongo can compile.
An ineligible query falls through to the next configured driver. Oplog is
available only when `MONGO_OPLOG_URL` is configured.
On Meteor 3.5+, override the app-wide order with
`METEOR_REACTIVITY_ORDER=oplog,polling` or:
```json
{
"packages":{
"mongo":{
"reactivity":["oplog","polling"]
}
}
}
```
On Meteor 3.5+, the `disable-oplog` package removes only the oplog step. It
does not disable change streams. Use `reactivity: ["polling"]` to force
polling. On Meteor 3.0 through 3.4, do not add these settings; upgrade first.
For duplicate observer events or intermittent login disconnects under core
change streams, check the resolved `mongo` version before rewriting queries or
disabling reactivity. `mongo@2.5.1` (Meteor 3.5.2) fixes replay of events already
covered by a causal primary snapshot. Earlier 3.5 packages lack that fix;
upgrade and rerun the failing sequence. This does not change driver eligibility
or justify dropping arbitrary application events by timestamp. Capture observer
ordering if the problem persists; use `meteor-debugging` for an unknown cause.
## Collation (Meteor 3.5+)
Use `collation` for locale-aware or case-insensitive selectors and sorting on
both Mongo and Minimongo. Back the server query with an index created using
`.meteor/versions`, `package.json`, and `mobile-config.js` when present.
Record host OS, target device/platform, installed native binary version,
and whether the task needs a development run, web update, or new binary.
2. Match prerequisites to the selected Meteor release and resolved Cordova
platform. Meteor 3.5.2 uses `cordova-lib@13.0.0`,
`cordova-android@15.1.0`, and `cordova-ios@7.1.1`; earlier releases have
different pins. Do not select the newest standalone Cordova platform
merely because it is available.
3. Choose the relevant reference below. Keep durable changes in the app's
platform/plugin declarations, configuration and assets; inspect generated
native output to verify what Meteor actually produced.
4. Rebuild/reinstall when native plugins, platform versions, permissions or
native configuration change. HCP can update compatible web code/assets;
it cannot supply missing native code or change installed binary metadata.
5. Verify on the target emulator/device or inspect the requested artifact.
Record command, versions, endpoint and observable result. A successful web
build alone does not validate a native app or a signed store artifact.
| Task | Read |
|---|---|
| Set up Android/iOS, add/remove platforms, run a device, choose WebView compatibility | [Toolchain and development](references/toolchain-and-development.md) |
| Change app metadata/assets, native preferences, access rules, plugins, permissions or build overrides | [Configuration and plugins](references/configuration-and-plugins.md) |
| Build Android artifacts or an iOS project, configure signing and prepare distribution | [Build and distribution](references/build-and-distribution.md) |
| Repair mobile update delivery, compatibility rejection, download or reload behavior | [Hot code push](references/hot-code-push.md) |
## Persistent state and runtime boundaries
-`.meteor/local/cordova-build/` is generated by default. If
`METEOR_LOCAL_DIR` is set, resolve the actual local directory before opening
or clearing its `cordova-build` child. Do not erase the whole local state
or local Mongo database to repair a Cordova cache.
-`mobile-config.js` is a build-time configuration file, not an application
module. `App.configurePlugin` supplies installation variables; it neither
installs a plugin nor runs its JavaScript API.
- Call native plugin APIs from client code guarded by `Meteor.isCordova`,
inside `Meteor.startup` or after equivalent device readiness. Meteor's
Cordova startup waits for `deviceready`; browser/server code must retain a
suitable fallback. Startup does not grant OS permissions automatically.
- A physical device's `localhost` is the device. Match `--mobile-server`
during development and `meteor build --server` for distribution to a
reachable endpoint. The embedded WebView's local content server is separate
from the Meteor backend and DDP connection.
## Neighboring workflows
| Request | Owner |
|---|---|
| Unknown crash, stuck data, or failure not yet isolated to native behavior | `meteor-debugging`, then return with the confirmed native boundary |
| Host the backend, configure Galaxy/Docker, deploy server changes, preserve the HCP client bundle | `meteor-deployment` |
| Rspack/SWC/module graph or a native npm addon such as `sharp` | `meteor-modern-build-stack` or `migrate-to-rspack` |
| OAuth provider/login behavior | `meteor-accounts`; use this skill for required Cordova plugin or native configuration |
| Explicit React Native/Expo or Capacitor app | Keep the chosen stack; this skill does not implement those integrations |
## Acceptance
Use [evaluation cases](references/eval-cases.md) to check native decisions,
earlier-release behavior, and neighboring-skill routing.
For `BackgroundColor`, use a supported `#` hex value, for example
`App.setPreference('BackgroundColor', '#ffffffff')` for opaque white. Old
examples using `0x...` caused Android build failures during Meteor 3 migrations.
Check the failing resource/preference before treating nearby Gradle deprecation
warnings as the cause. Preserve the intended color and the target platform's
channel ordering. See the [confirmed 3.3.2 repair](https://forums.meteor.com/t/solved-migration-from-2-16-to-3-3-2-break-cordova-android-build/64274/2)
and the current [configuration example](https://docs.meteor.com/api/app).
| Need | App-level source | Check after generation |
|---|---|---|
| ID, display name, version | `App.info` | Native application ID and displayed/build versions; preserve published IDs |
| Platform preference | `App.setPreference(name, value, platform)` | Correct platform section; supported preference for the pinned platform/plugin |
| Icons and splash images | `App.icons`, `App.launchScreens` with project-relative assets | Accepted keys, existing source images, generated resources on target devices |
| Plugin installation variables | `App.configurePlugin(id, variables)` | Exact installed plugin ID and generated native configuration |
| Extra XML / platform resources | `App.appendToConfig`, `App.addResourceFile(src, target, platform)` | Correct generated XML/resource target, without replacing unrelated configuration |
| Native files outside those APIs | App-root `cordova-build-override/`, mirroring the generated Cordova project tree | Narrow override remains compatible with the selected native platform |
Meteor copies build overrides into the generated Cordova project. Prefer the
configuration APIs for values they own; a whole generated `config.xml`, Gradle
file, or project copy can mask future Meteor/platform changes. Rebuild and
inspect output after changing native configuration. Do not treat edits under
`.meteor/local/cordova-build` as the permanent source.
`App.settings` reads the build's settings file, while native client runtime
settings use its `public` subtree. A private settings value becomes exposed
if the build copies it into plugin variables, XML or client assets. Use
client-appropriate identifiers in native config and keep server credentials
on the server; do not log full settings while checking values.
HCP replaces compatible web code/assets in the installed Cordova shell. It
does not install new native plugins, upgrade Cordova platforms, or alter
native permissions, app identity, icons or signing. A Meteor upgrade can
change the native compatibility contract; do not assume every installed
binary can accept its client bundle.
Compare generated native changes, not merely edited filenames or the Meteor
release label. The compatibility hash covers platform/plugin versions; it does
not capture every native permission or configuration change. Those changes
still need a new binary even when the hash is unchanged.
When a change needs native code/configuration, rebuild and distribute a new
binary and preserve backend compatibility for old installations. Do not make
`AUTOUPDATE_VERSION` or another compatibility override the default way to
silence a platform/plugin mismatch. Such an override needs a verified native
and JavaScript API contract across the installed client population.
## Find the failed stage
Inspect `.meteor/versions` for HCP packages (`hot-code-push`, `autoupdate`,
`reload`) and the native webapp plugin; minimal/custom apps may omit them.
The default `meteor-base` setup supplies HCP. Compare an installed native
build with its intended server, not just with a successful browser reload.
| Stage | Evidence and next decision |
|---|---|
| Backend produced the update | Verify the deployed `web.cordova` bundle and changed version. A `--server-only` deployment can serve HCP; a build excluding that client target cannot. |
| Device reached the server | Check the embedded build URL, `--mobile-server` for local work, public `ROOT_URL`, and any DDP override. Distinguish network/TLS/cleartext failures from compatibility. |
| Client learned the version | Inspect DDP subscription/device logs and changed version hashes. A fixed `AUTOUPDATE_VERSION` must be changed when intentionally delivering another update. |
| Client fetched the current manifest | Compare the version in `/__cordova/manifest.json` through the public proxy/CDN and directly at the origin. Inspect GET response headers and cache hits. If the public manifest is stale, bypass caching for this endpoint and purge its stale copy; keep versioned asset caching separate. |
| Native shell accepted it | Read compatibility rejection logs. A platform/plugin mismatch calls for the native-version comparison and binary rollout above. |
| Assets downloaded | Check the failing URL, response, connectivity and device storage. Large `public/` files can block update downloads; relocate only confirmed problem assets as the app requires. |
| Pending version became active | Verify download completion, pending-version selection and reload. Custom reload code can reload the old bundle if it bypasses the native switch. |
| New client started | Capture the first startup failure or rollback on the device. A version notification or download alone does not prove successful startup. |
An iOS-only production failure can be a cached manifest even when development
and Android update correctly. A [Meteor 3.2.2 reporter confirmed this repair](https://forums.meteor.com/t/cordova-ios-hot-push-code/63707/6).
Meteor marks its manifest non-cacheable; a proxy must preserve that behavior.
Verify a subsequent deployment changes the public manifest version and reaches
the device. A fresh manifest with a real plugin mismatch still requires the
compatibility decision above. Use `meteor-deployment` for the proxy change.
Use selected version values and stage transitions for diagnostics. Never log
full runtime settings, session credentials or private payloads to inspect HCP.
Collect native logs through Android Studio/Xcode and WebView debugging when
needed; use `meteor-debugging` if the failure still spans unknown layers.
## Reload behavior
Cordova HCP reloads the whole client even for CSS-only changes. Browser CSS
refresh and development HMR are different paths; do not promise state-preserving
CSS HMR in a production native app merely because a browser supports it.
Prefer the built-in reload path. When an app already customizes reloads,
inspect that code against its resolved Meteor/reload/webapp-plugin versions:
the native pending bundle must be selected before a forced page reload. The
docs describe `WebAppLocalServer.switchToPendingVersion` and the retry callback
of `Reload._onMigrate`; these are version-sensitive integration hooks, not a
reason to add custom reloader code to every app. Preserve unsaved-state handling
and remove temporary instrumentation after reproducing the repair.
For local HTTP failures, see
[configuration and plugins](configuration-and-plugins.md). A development-only
network exception is not a production compatibility or TLS repair.
| Early Meteor 3 Cordova startup fails after adding accounts, with a misleading missing `core-js` error from `url/legacy.js` | `url@1.3.5`, shipped in Meteor 3.1 | Check for a shadowing `packages/url` override before choosing a compatible fixed package/release, then verify account startup. Adding app-level `core-js` or removing accounts does not repair the URLSearchParams integration. [Fix](https://github.com/meteor/meteor/pull/13459) |
| `Map.keys`, `Map.entries` or iteration fails in a modern library only in the Cordova bundle | `ecmascript-runtime-client@0.13.0`, shipped in Meteor 3.4.1 | Check whether legacy polyfills replaced native Map/Set/Symbol. Modern transpilation alone is not this fix. Use the compatible fixed package/release; for a constrained branch, verify an app-local backport against its supported WebViews. Do not edit the global Meteor cache or downgrade unrelated UI libraries. [Meteor 3 confirmation](https://forums.meteor.com/t/solved-vue3-does-not-work-with-cordova/61109/10) |
| Meteor 3.4 Rspack `android-device`/iOS development produces SockJS `Invalid frame header` or proxy errors, including in a desktop browser attached to that native run | Atmosphere `rspack@1.1.0`, shipped in Meteor 3.4.1 | Use the fixed native integration that skips the desktop HMR bootstrap/proxy. Confirm the native run-mode reproduction and resolved package; healthy fixed versions or production proxy failures need separate diagnosis. [Fix](https://github.com/meteor/meteor/pull/14226) |
On earlier constrained releases, verify package compatibility before a
selective update or backport. Retest both the native client and any affected
browser clients. Do not force a framework upgrade contrary to the app's
release constraint or apply these repairs to an unexplained white screen.
| `SERVER_MERGE` | Default. Tracks merged document fields across publications and sends deltas. |
| `NO_MERGE` | Tracks sent document IDs so unsubscribe can remove them. Use when the collection is owned by one publication. |
| `NO_MERGE_NO_HISTORY`| Remembers nothing and sends no removals on stop. Reserve for send-and-forget queues where stale client documents are intentional. |
Rspack compiles application modules while Meteor still compiles Atmosphere
packages and assembles the final bundle. Audit both systems at the boundaries
that shape the browser graph.
## Build separate reachability graphs
Start from every configured root:
-`meteor.mainModule.client`;
-`meteor.testModule.client`, or the client side of `testModule`;
- client entry points declared by local Atmosphere packages.
Follow static imports, re-exports, and literal `require()` calls. Record dynamic
`import()` edges separately because they are intentional split points. Do not
classify a module only from `client/`, `server/`, or `imports/` in its path.
## Resolve clean-checkout inputs
Resolve every static edge from each client and client-test root in a clean
checkout before activation. A missing module can be:
- a checked-in source file;
- a generated file excluded by Git;
- a virtual module supplied by a loader or plugin;
- an alias resolved by Rspack, TypeScript, Babel, or SWC;
- a package export selected by browser conditions.
Do not require every import target to exist as a physical file. First apply the
active aliases, package exports, extensions, and loader rules. When a target is
generated, find its producer and require a deterministic command before
development, test, CI, and production builds that consume it. Do not commit
generated output automatically. Reproduce from a clean checkout with caches
empty and fail preflight if no documented producer can create the input.
Server unit tests do not prove this graph compiles. Run test-mode client
compilation or a browser-backed client suite, plus a production client build.
## Flag risky client-reachable modules
| Finding | Interpretation | Action |
|---------|----------------|--------|
| `module.exports` or `exports.*` in an ESM graph | Mixed module ownership can abort evaluation or defeat static analysis. | Convert the module consistently to ESM or move it behind a server boundary. |
| Node built-in import | Browser code may be reaching server-only behavior. Rspack does not add Node polyfills automatically. | Move the module server-side or document and configure an intentional browser polyfill. |
| Local package main module has no architecture | Meteor may load server dependencies on the client. | Add the correct `client` or `server` architecture in `package.js`. |
| Meteor package shim writes CommonJS exports | A compatibility shim can become the first failed module in the client chain. | Export valid ESM or keep the shim outside the Rspack client graph. |
Node built-ins to inspect include bare and `node:` forms of `fs`, `path`,
If the app has no client UI (API servers, microservices, workers), set
only `mainModule.server`:
```json
{
"meteor":{
"mainModule":{
"server":"server/main.js"
}
}
}
```
Rspack builds the server bundle; the client side is skipped.
## Nested imports
Detection: enable verbose mode and watch for `(app)` files failing with
`Error: 'import' and 'export' cannot be used outside of module code`.
```json
"meteor":{
"modern":{"transpiler":{"verbose":true}}
}
```
`(package)` files are out of scope. Atmosphere packages stay on the Meteor
bundler under the integration.
### Rewrites
```javascript
// 1. Top-level
import{aasb}from"./c";
if(condition)console.log(b);
// 2. Dynamic import. Returns a Promise; the function becomes async.
if(condition){
const{a:b}=awaitimport("./c");
console.log(b);
}
// 3. require
if(condition){
const{a:b}=require("./c");
console.log(b);
}
```
Use the dynamic-import form when the goal was code-splitting (the original
Meteor nested-import use case). Use `require` for purely synchronous
loading in a sync scope. Inventory intentional `import()` split points before
cleanup and compare generated chunks afterward. Do not silently convert a lazy
boundary into an eager import.
## Default-import interop for CommonJS
Old Meteor accepted `import x from "some-cjs"` for a package whose source
is `module.exports = ...`. Rspack + SWC do not by default.
```javascript
// before
importxfrom"some-cjs-lib";
// after, preferred
import*asxfrom"some-cjs-lib";
```
If the upstream package shape makes namespace import wrong (e.g. a single
default export reshaped to namespace), the SWC interop knob restores
Meteor's old behavior:
```json
{
"module":{
"type":"commonjs",
"noInterop":false,
"importInterop":"node"
}
}
```
Cost: SWC emits CommonJS everywhere. Rspack loses ES module boundaries,
so tree-shaking and static analysis are off across the app. Migrate the
handful of imports instead unless there is no alternative.
## Aliases
Three places to keep in sync:
```javascript
// rspack.config.js
const{defineConfig}=require('@meteorjs/rspack');
module.exports=defineConfig(Meteor=>({
resolve:{
alias:{
'@ui':'/imports/ui',
'@api':'/imports/api',
},
},
}));
```
```json
// tsconfig.json (IDE + ESLint)
{
"compilerOptions":{
"baseUrl":".",
"paths":{
"@ui/*":["imports/ui/*"],
"@api/*":["imports/api/*"]
}
}
}
```
```json
// .swcrc (only if SWC needs to resolve the alias during transpile)
{
"jsc":{
"baseUrl":"./",
"paths":{"@ui/*":["imports/ui/*"]}
}
}
```
Limits:
- SWC `paths` resolve `import` only, not `require(...)`.
- Rspack `resolve.alias` resolves both `import` and `require`. Prefer
Rspack when both forms are in use.
For dynamic aliases by env, use `swc.config.js` (a function that returns
the SWC config).
## Symlinks and monorepos
Choose resolution from how shared code is consumed:
| Shared-code model | Rspack behavior | Action |
|-------------------|-----------------|--------|
| npm, pnpm, or Yarn workspace package imported by package name | Default package resolution follows the real package. | Keep the default. |
| App-local source symlink imported by its path inside the app | Default resolution follows the real path and can lose the app-local import context. | Set `resolve.symlinks: false`. |
```javascript
module.exports=defineConfig(Meteor=>({
resolve:{symlinks:false},
}));
```
Do not disable symlink resolution for every monorepo. Apply it only when the
application intentionally shares source by symlink location instead of package
name. Validate imports, file watching, a development rebuild, and a production
build from the consumer app.
## Reserved build folders
Do not commit, edit, or import from:
```text
_build/ # Rspack entry + intermediate app code
public/build-assets/ # client static assets
public/build-chunks/ # dynamic-import code splits
private/build-assets/ # server assets
```
Auto-added to `.gitignore` the first time. If the project already uses
these names, rename:
```json
{
"meteor":{
"buildContext":"build",
"assetsContext":"assets",
"chunksContext":"chunks"
}
}
```
`.gitignore` is not a tool ignore. Add the active folder names to every
recursive tool that scans the repository, including Biome or ESLint,
TypeScript, test discovery, coverage, and IDE indexing. Run those tools once
after an Rspack build so generated files cannot hide a missing exclusion.
Do not add the active build context to `.meteorignore` or `METEOR_IGNORE`.
Meteor consumes the Rspack-generated main and test modules from that directory.
See `client-graph-preflight.md` for renamed contexts and source-tree scanning.
## Verifying a migration
Verify from a clean clone, not only from a developer tree with cached files
or ignored settings:
1. The existing manager's frozen install preserves its lockfile: `meteor npm ci`
for npm, root `pnpm install --frozen-lockfile` for pnpm workspaces, or the
Prompt: "After `meteor add rspack`, my build fails with `Error: 'import'
and 'export' cannot be used outside of module code` on `imports/app.js`.
What do I do?"
Pass if the agent identifies a nested import (an ES `import` inside a
conditional, function, or block), explains it is not standard syntax, and
shows the three fixes: move to top, dynamic `import()`, or `require`.
Bonus: mentions verbose mode for finding more `(app)` failures.
## Case 2: SCSS plugin replacement
Prompt: "I use `fourseven:scss` and want to add Rspack. How do I migrate
my SCSS?"
Pass if the agent removes `fourseven:scss` from `.meteor/packages`,
installs `sass-embedded` and `sass-loader`, and adds an SCSS rule to
`rspack.config.js` using `type: 'css/auto'` and the
`api: 'modern-compiler'` option. Bonus: notes that `meteor create --full`
on 3.4.1+ ships this exact setup.
## Case 3: default-import breaks after migration
Prompt: "After enabling Rspack, `import x from "some-cjs-lib"` returns
undefined. The package uses `module.exports = ...`. What changed?"
Pass if the agent explains that Rspack + SWC do not provide the old
Meteor default-import interop, and proposes `import * as x` as the first
fix. If the agent also explains the `.swcrc``noInterop: false`
workaround, it must call out the tree-shaking cost.
## Case 4: CI cannot find rspack.config.js
Prompt: "Local builds work but Docker fails with `Could not find
rspack.config.js`. What's missing?"
Pass if the agent checks the project root, config file and earlier dependency
errors, treating an incomplete npm upgrade as a hypothesis. It should prefer
resolving required dependencies locally, committing `package.json` and the
lockfile, then using `meteor npm ci` with build-time dev dependencies in Docker.
Fail if it asserts the cause from this error alone or suppresses install errors.
## Case 5: server-only app
Prompt: "I have a background-worker Meteor app with no UI. Can I use
Rspack? How do I configure it?"
Pass if the agent confirms it works, shows a `package.json` with only
`mainModule.server`, and notes that Rspack will skip the client build
entirely.
## Case 6: integration major mismatch
Prompt: "I upgraded from Meteor 3.4 to 3.4.1 but kept
`@meteorjs/rspack@^1.0.0`. The config now fails in a clean build. Should I
align it with my `@rspack/core` major?"
Pass if the agent requires `@meteorjs/rspack` v2 for Meteor 3.4.1, explains
that Meteor 3.4.1 pairs `rspack@1.1.0` with `@meteorjs/rspack@2.0.1`, keeps its
version independent from core/CLI, and uses startup auto-install or explicit
`meteor update --npm` to update and commit the dependency files.
## Case 7: generated files break Biome
Prompt: "The app builds with Rspack, but `biome check .` now reports errors
inside `_build/main-dev`. The directory is already in `.gitignore`."
Pass if the agent explains that Git ignores do not necessarily configure
Biome and adds all active Rspack output folders to the tool's own ignore.
It should rerun Biome after a build.
## Case 8: cached migration passes, clean clone fails
Prompt: "Rspack works in my existing checkout, but a fresh clone cannot
start because an ignored settings file is missing. Is the migration done?"
Pass if the agent rejects the cached-checkout result, requires a tracked
nonsecret settings fixture or documented environment setup, and verifies
development, tests, E2E, production build, and clean Git status from a fresh
clone.
## Case 9: CommonJS assignment in the client graph
Prompt: "After Rspack, every page is blank. A helper imported through a shared
model uses `module.exports`, but the file lives outside `client/`. Server tests
pass. Should I enable global CommonJS interop?"
Pass if the agent traces reachability from the client entry, distinguishes this
from default-import interop, and either converts the reachable module to
consistent ESM or moves it behind a server boundary. Fail if it classifies the
file by pathname or changes `.swcrc` globally without inspecting the graph.
## Case 10: Node built-in enters the browser
Prompt: "The client build now fails on `crypto` and `stream`. The import comes
from a local Atmosphere package whose `api.mainModule('index.js')` contains
server lockout logic."
Pass if the agent inspects the package architecture, restricts the entry to
`server` when appropriate, and verifies a browser production smoke. Accept a
polyfill only when the behavior is intentionally browser-compatible.
## Case 11: `_build` added to `.meteorignore`
Prompt: "I copied generated paths from `.gitignore` into `.meteorignore`. Now
Meteor says it cannot find `_build/main-prod/server-meteor.js`."
Pass if the agent identifies `_build` as the Rspack-to-Meteor handoff, removes
the active build context from `.meteorignore`, checks renamed contexts, and
keeps the path ignored only by Git and unrelated recursive tools.
## Case 12: lazy chunks under a path prefix
Prompt: "The production app works at `/`, but under `ROOT_URL=https://host/app`
opening a lazy route requests `build-chunks/build-chunks/x.js`."
Pass if the agent tests a real dynamic import under the deployed URL prefix,
fixes the public base without making the import static, and verifies that the
chunk loads and executes.
## Case 13: server healthy, browser blank
Prompt: "The Rspack production bundle builds, starts, and returns HTTP 200, but
the browser page is blank. Can I call the migration complete?"
Pass if the agent rejects server health as sufficient, finds the first browser
module exception, inspects the client graph, and requires a browser smoke
against the extracted production bundle.
## Case 14: CSS outside the entry folder
Prompt: "After defining `client/main.js` for Rspack, a global stylesheet in
`styles/main.css` is no longer included. I need Meteor to keep compiling it and
do not want to import it through an Rspack loader."
Pass if the agent adds the stylesheet to `meteor.modules`, does not add
JavaScript there, and verifies the final stylesheet output. Bonus if it explains
that importing through an Rspack loader is the faster-HMR alternative.
## Case 15: app-local source symlink
Prompt: "My Meteor app imports `imports/shared` through a source-directory
symlink. Rspack resolves the real directory outside the app and breaks relative
imports. Should every pnpm workspace set `resolve.symlinks: false`?"
Pass if the agent distinguishes app-local source symlinks from package-name
workspace imports, sets `resolve.symlinks: false` only for the former, and
validates watching and production bundling from the consumer app.
## Case 16: CSS delegation depends on Meteor version
Prompt: "I configured `postcss-loader` while migrating a Meteor 3.4.0 app to
Rspack. Meteor and Rspack both emit the stylesheet. Should I add every generated
folder to `.meteorignore`?"
Pass if the agent identifies automatic stylesheet delegation as Meteor 3.4.1+
behavior, prefers upgrading, and uses only a narrow temporary stylesheet ignore
when 3.4.0 is an intentional constraint. It must protect the active build
context and verify the expected CSS appears exactly once in development and
production.
## Case 17: custom build plugin has hidden behavior
Prompt: "A custom Meteor build plugin compiles `.theme` files, copies fonts in
production, and injects an alias in tests. Rspack has a loader for `.theme`, so
can I remove the plugin now?"
Pass if the agent inventories all three capabilities, configures equivalent
Rspack behavior, and validates development, test, and production outputs before
removal. If the two pipelines conflict, it must use a checkpoint and one
reversible activation/removal change. Fail if it treats the matching extension
as complete parity or upgrades the UI framework unnecessarily.
## Case 18: ignored generated module in the client graph
Prompt: "Server tests pass, but a clean production client build cannot resolve
`./generated/schema.json`. The file is Gitignored and exists on developer
machines after another tool runs. Should I commit it?"
Pass if the agent traces the client and client-test graph, identifies and runs
the deterministic producer before every consuming path, and validates clean
test-mode and production client builds. It must not commit generated output
automatically. Fail if it accepts server tests as client compilation evidence.
## Case 19: successful test command runs no client tests
Prompt: "`meteor test --once` exits zero and reports six server tests, followed
by `browser client tests were not run`. The Rspack changes are client-only. Can
I merge?"
Pass if the agent requires a browser driver or browser-backed client suite,
checks expected suite counts, compiles the real test-mode client entry, and
retains a production browser smoke. Fail if it treats exit zero or server-only
tests as sufficient.
## Case 20: current helper copied into Meteor 3.4.0
Prompt: "A current Rspack example uses `Meteor.persistDevFiles`,
`Meteor.replaceSwcConfig`, and `Meteor.enablePortableBuild`. My migration is
fixed on Meteor 3.4.0. Can I paste those helpers?"
Pass if the agent identifies Meteor 3.4.1 and `@meteorjs/rspack` v2 as the
minimum for all three helpers, checks the resolved Atmosphere and npm package
versions, and either upgrades the paired Meteor integration or designs and
tests direct Rspack equivalents. Fail if it installs v2 alone or assumes
current `devel` helper availability applies to Meteor 3.4.0.
## Case 21: cache panic with valuable local data
Prompt: "Meteor 3.5.2 Rspack exits before its first compile and reports an
incompatible persistent cache. I have valuable data in local Mongo. Give me
the smallest recovery step."
Pass if the agent preserves the first error, stops affected build processes,
resolves and clears only the Rspack cache, and retries. It may escalate to
`meteor reset` only after checking its release behavior. Fail if it deletes
`.meteor/local`, uses `--db`, disables cache permanently, or raises heap limits
without evidence of OOM.
## Case 22: cache recovery on an earlier integration
Prompt: "Our Rspack migration must remain on Meteor 3.4.0. The first compile
hangs after a child-process error. Can I rely on the 3.5.2 fail-fast behavior
and delete .meteor/local to reset it?"
Pass if the agent captures the child error, identifies the later fail-fast fix,
honors the pinned release, and protects local Mongo. It checks reset semantics
or chooses targeted cache recovery only when cache evidence supports it.
## Case 23: upgrade with immutable CI dependencies
Prompt: "We migrated to Meteor 3.5.2 and opted out of npm auto-install. A
clean Docker build lists outdated Rspack dependencies. Prepare the dependency
workflow without letting CI rewrite our lockfile."
Pass if the agent checks the 1.3.0/2.2.0 integration pairing and reported
minimums, resolves and reviews the dependency files locally, preserves runtime
helpers and build-time dev dependencies, and verifies a clean immutable build.
## Case 24: Rspack 2 config migration
Prompt: "Upgrade our Meteor 3.5.2 Rspack app to 3.6-beta.0. Its config uses experiments.css, experiments.cache, output.libraryTarget, webpack-merge, and .swcrc. What must change?"
Pass if the agent: Uses the beta package pairing, removes obsolete CSS experiment, moves cache top-level, reviews library.type while preserving Meteor output, replaces webpack-merge with rspack-merge, and preserves Meteor wrapper .swcrc discovery despite raw Rspack 2 behavior.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 25: npm peer transition warning
Prompt: "On Meteor 3.6-beta.0 autoInstallDeps is false and installed Rspack core/CLI/React Refresh are 1.x. The printed npm update command hits old peer constraints. Should we set legacy-peer-deps globally?"
Pass if the agent: Rejects a global bypass, verifies the coordinated Rspack 2 transition, permits a scoped npm --legacy-peer-deps invocation for confirmed old peers, and notes the beta manual warning may omit the flag. Does not apply the flag to pnpm or Yarn.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 26: preserve an existing Workbox migration
Prompt: "We are moving an existing Meteor app to the 3.6 beta Rspack pairing. It uses a Workbox-generated service worker. Must we discard it for the new Blaze PWA scaffold?"
Pass if the agent: Treats Workbox as optional but valid, inventories generation and cache/update behavior, proves migration parity, and does not overwrite the existing app or promise offline data.
Fail if it contradicts these boundaries or invents unsupported commands.
## Case 27: automatic upgrade of an existing Rspack app
Prompt: "Our existing Meteor 3.5.2 app already uses Rspack and automatic npm installation is enabled. Upgrade to 3.6-beta.0. Must we run meteor update --npm separately, re-add rspack, or regenerate our working config?"
Pass if the agent gives the release update then normal `meteor run`, explains
startup's paired dependency update, and reviews/commits the resulting version
files and authoritative lockfile. It keeps valid entries/configuration and
checks custom tooling separately. Fail if it requires the extra npm command,
re-adds Rspack or promises automatic rewriting of all custom configuration.
## Case 28: beta startup with deliberate auto-install opt-out
Prompt: "We are upgrading our Rspack app to Meteor 3.6-beta.0, but meteor.autoInstallDeps is false and CI must never rewrite dependencies. Will normal startup still upgrade everything? Give the local preparation and CI boundary."
Pass if the agent respects the opt-out, prepares the coordinated dependency
set locally, reviews and commits changes, then uses the existing manager's
frozen install with build-time dev dependencies. It explains that explicit
`meteor update --npm` overrides the opt-out for that invocation. Fail if it
silently enables auto-install, mutates locks in CI or treats opt-out as success
despite unresolved required dependencies.
## Case 29: Svelte preprocessing after the beta upgrade
Prompt: "After upgrading to Meteor 3.6-beta.0/Rspack 2, a Skeleton Svelte component fails during TypeScript preprocessing. We use svelte-loader and svelte-preprocess with PostCSS. Our tsconfig has extends and path aliases. What can we learn from Complex Todos without replacing our build setup?"
Pass if the agent checks resolved compiler/loader/preprocessor versions and
the first error, describes the example's Svelte update and TypeScript dev
dependency/configuration, and merges relevant `target`/`verbatimModuleSyntax`
options while preserving existing settings. It retains needed PostCSS and
verifies an affected component and CSS in development and production. Fail if
it treats observed versions as universal minimums, overwrites the config or
migrates the app to Vite/SvelteKit.
## Case 30: Lingui plugin major differs from the application toolchain
Prompt: "On Meteor 3.6-beta.0 with @rspack/core 2.2.0, our builtin:swc-loader fails loading @lingui/swc-plugin 5.11.0. The other Lingui tools are 5.x. Should I update only @swc/core, remove the plugin, or upgrade every Lingui package to 6? Notes Offline changed the plugin to 6.7.0."
Pass if the agent identifies Rspack's embedded SWC as the relevant host,
checks resolved plugin/runtime compatibility, and treats the example's
plugin update as a candidate rather than a universal pin. It preserves
required macro transforms, explains independently versioned tooling, and
verifies representative transformed and translated output. Fail if any of the
three proposed shortcuts is presented as sufficient without that evidence.
## Case 31: newer example fix on a pinned older compiler
Prompt: "Our Meteor 3.5.2 app must keep Rspack 1 for now. Lingui builds correctly. Should we copy Notes Offline's @lingui/swc-plugin 6.7.0 upgrade to prepare for Meteor 3.6?"
Pass if the agent preserves the working release/integration pairing, rejects
a speculative plugin upgrade and requires compatibility with the actual
resolved compiler before any later change. Fail if it treats the PR's plugin
version as a Meteor-wide floor or silently moves this app to Rspack 2.
## Case 32: raw Rspack 2 advice versus Meteor configuration
Prompt: "The Rspack 2 guide says its packages are pure ESM, dev-server is explicit, and resolve.roots defaults to empty. After upgrading our Meteor app to 3.6-beta.0, should I replace our working CommonJS rspack.config.js with a standalone ESM config and rebuild all resolution rules? Our host CI image still uses Node 18."
Pass if the agent distinguishes host Node from Meteor's build runtime,
configuration/output and notes that Meteor supplies dev-server and project
roots. It inspects effective configuration and custom overrides before
changing resolution. Fail if it assumes raw defaults replace Meteor's values,
converts the project to ESM unconditionally or ignores the old host runtime.
Also fail if it calls host Node 18 the proven build blocker without checking
whether the command uses Meteor's supported bundled Node instead.
## Case 33: beta feedback without overstating validation
Prompt: "All five examples in PR #50 started, so can we say every plugin and offline/production behavior is verified? My beta app still fails in a custom loader. Help me prepare feedback; do not post anything."
Pass if the agent limits the PR claim to reported migration/startup, requires
the affected feature and applicable production/offline checks, and drafts a
redacted reproduction checklist with releases, resolved toolchain, runtime,
config, command/mode, expected/actual result and first error. It distinguishes
base integration from app tooling without assigning unproven blame. Fail if
it claims tests were run, dismisses all plugin issues as outside Meteor, or
posts a report.
## Case 34: new-app setup is not a migration
Prompt: "I'm creating a new Meteor 3.6-beta.0 app, not upgrading an existing one. I need the initial Rspack setup and an explanation of defineConfig versus extendConfig. Which skill owns this?"
Pass if the agent selects `meteor-modern-build-stack` for setup/configuration
helpers, reserving `migrate-to-rspack` for existing-app migration compatibility.
Fail if it requires a legacy-plugin removal or Rspack 1-to-2 migration first.
## Case 35: a working older plugin on Rspack 2
Prompt: "We use Rspack 2.2.0 and @lingui/swc-plugin 5.11.0. A simple macro compiles and renders correctly. Must we upgrade to 6.7.0 because Notes Offline did? Does our smoke prove its reported failure was wrong?"
Pass if the agent rejects both inferences: it preserves compatible working
tooling without a speculative upgrade and limits the smoke to its actual
input/mode. It requires reproduction through the affected JSX/catalog/loader
path and applicable development/production checks before a broader claim.
Fail if it declares all plugin 5.x versions broken on Rspack 2, forces the
example pin, or dismisses a different project's failure from this one smoke.
the authoritative lockfile and custom `rspack.config.*`.
2. With default `meteor.autoInstallDeps` enabled, update then start normally:
```bash
meteor update --release 3.6-beta.0
meteor run
```
Startup checks and updates the required Rspack project dependencies. A
separate `meteor update --npm` is unnecessary. Review the resulting
manifests, Meteor version files and lockfile before committing them.
If `meteor.autoInstallDeps: false`, respect that choice: prepare the paired
dependencies explicitly in an authorized local workflow, then commit and
test a frozen install. `meteor update --npm` overrides the opt-out for that
invocation; do not put a lockfile-rewriting step in immutable CI.
3. The beta's required npm minimums are core/CLI/dev-server 2.2.0, Meteor integration
3.0.0-beta.1, SWC core 1.15.32, helpers 0.5.23 and Rsdoctor 1.5.9.
Keep helpers in runtime dependencies, the bundler tools in dev dependencies.
Detected React adds refresh plugin 2.0.0 and refresh runtime 0.17.0.
Record the resolved versions: compatible newer patches can satisfy these
minimums without matching the original examples' lockfiles exactly.
4. With npm and installed Rspack 1.x peers, the automatic upgrade uses
`--legacy-peer-deps`. The beta's manual warning can omit it. If that exact
coordinated update is rejected for stale peers, use the flag for that
invocation, review the lockfile and validate the installed majors. Do not
use `--force`, a global peer bypass or a flag copied into pnpm/Yarn.
5. Keep pnpm/Yarn workspace ownership. Resolve the manager at the workspace
root, add dependencies from the nested Meteor app, and commit its manifest
plus the root lockfile. Preserve intentional local dependency protocols.
## Review app-owned overrides
Meteor composes its base integration configuration and creates a default file
if none exists. It does not rewrite an existing `rspack.config.*` or migrate
every third-party loader/plugin. Inspect the effective merged configuration
before applying raw Rspack advice.
| Existing customization | Action on the beta pairing |
|---|---|
| `experiments.css` | Remove the obsolete option; the integration already supplies CSS rules with `type: "css/auto"`. Test CSS Modules and loader output. |
| `experiments.cache` | Use top-level `cache`; normally retain Meteor's persistent-cache defaults or `Meteor.setCache(false)` for a measured diagnostic. |
| `output.libraryTarget` | The upstream form is `output.library.type`, but Meteor owns final output. Remove an unnecessary override rather than replacing Meteor's output object. |
| `webpack-merge` in app-owned configuration | Use a compatible `rspack-merge` or Meteor's `extendConfig`; install a direct dependency if the app imports it. Preserve nested rules. |
| Missing TypeScript re-export diagnostic | Meteor defaults `module.parser.javascript.exportsPresence` to `"warn"` for SWC-stripped type exports. Inspect a custom strict override and distinguish types from missing runtime exports; do not disable checks globally. |
| `.swcrc`, `swc.config.js`, `swc.config.ts` | Keep valid Meteor configuration: the integration reads it and passes loader options even though raw Rspack 2 no longer auto-loads `.swcrc`. |
| Manual React Refresh plugin/bootstrap | Verify Meteor's automatic injection first; do not introduce a second refresh stack. |
Also check these [upstream migration boundaries](https://www.rspack.dev/guide/migration/rspack_1.x):
| Surface | Migration check |
|---|---|
| Node and ESM | Rspack 2 requires Node `^20.19.0 \|\| >=22.12.0`. Meteor 3.6-beta.0 bundles Node 24.15.0; host Node 18 alone does not prove a Meteor build incompatibility. Identify which binary actually invokes each tool before upgrading that runtime. Keep valid Meteor CommonJS configs/output despite pure-ESM Rspack packages. |
| Dev server | `@rspack/dev-server` is now explicit; Meteor's dependency check supplies it. Review custom `devServer.proxy` and `watchFiles` against the v2 guide before reusing old shapes. |
| Resolution | Upstream changes cover `.wasm` extension lookup, CSS `@import` conditions and empty `resolve.roots`. Meteor supplies explicit extensions and project roots. Inspect `resolve.byDependency` and custom overrides; test the failing import before changing resolution globally. |
| Custom plugins | Review the plugin's Rspack 2 support and the [2.0 breaking-change overview](https://www.rspack.dev/blog/announcing-2-0), including compiler hook and stats API changes when used. |
Apply changes to app-owned overrides, not generated `_build` output or a
replacement standalone configuration. For framework loaders, Svelte
Loaded 100 of 1741 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.