-
-
Notifications
You must be signed in to change notification settings - Fork 0
0.22.0
Hussein Jarrar edited this page Sep 12, 2026
·
2 revisions
36 changes · 11 Bugfixes, 3 New Features, 3 New UI Features, 19 Chores · 110 points.
-
RADD-869 Docs truth pass: security-relevant docstring lies
authcommentsitemsmcpviews· 2 pts ·3631d3c0What is wrong (report 04,research/audit-2026-08/04-misleading-docs-comments.md): docstrings/comments that misdescribe security-relevant behavior.merge_users(auth/service.py:693) promises "account deactivated (kept for audit)" while the code hard-DELETES the source row — echoed indelete_user(:955). The… -
RADD-880 page-print proof asserts on a selector that exists nowhere (vacuous pass)
pages· 1 pts ·a3ab7c33web/scripts/page-print-proof.mjs:136checks!!document.querySelector("[data-page-tree]")to prove the print view excludes the page tree — butdata-page-treeis set nowhere in web/src, so the assertion passes unconditionally. Exactly the vacuous-check class CLAUDE.md warns is worse than no test. -
RADD-879 Editor diff-review CSS styles class names the decoration plugin never emits
editor· 1 pts ·46fb7a7aeditor.css:184-194styles.milkdown-diff-insert/-block-insert/-delete/-block-delete, but the forked decoration plugin emitsmilkdown-diff-added/-added-block/-removed(diff/decoration-plugin.ts:239,314,354-356). The styled names never appear; the emitted names are styled nowhere — non-textblock deletions… -
RADD-875 Issue-rail state chip ships a drifted second copy of the workflow palette
items· 2 pts ·0591fd82IssueProperties.tsx:22-35hardcodesCATEGORY_CHIPhexes:in_progress#eab308 (YELLOW) where the design system's traffic-light reading is green (--chart-progress),donegreen where the system says slate,triage/backlogalso differ — and the map is theme-blind. index.css declares--chart-*as "ONE source… -
RADD-878 _rebalance_ranks issues one UPDATE per item, instance-wide, inside a drag request
items· 2 pts ·23fec0f4items/service/queries.py:289-300— when a rank midpoint collapses during drag-to-rank,_rebalance_ranksselects EVERY item id in the instance (not even project-scoped) and issues one UPDATE per row. Against the 503k-item perf dataset that is 503k statements in one interactive transaction, lock-contending every… -
RADD-877 CommitBeforeSendMiddleware buffers entire file downloads in RAM
attachmentsbackup· 3 pts ·28f2e7efradd/middleware.py:29-53buffers every non-SSE response's body messages in a Python list until the app (including session teardown) finishes — soGET /backups/{name}/downloadholds a potentially multi-GB artifact fully in memory before the first byte leaves, and every concurrent attachment proxy holds its full… -
RADD-872 sweep_expired_grants never runs — the kernel TaskSpec registry has zero readers
accesskernel· 2 pts ·3687c5a3access/__init__.py:19registerssweep_expired_grantsas the codebase's onlyTaskSpec, but nothing anywhere readsregistries.tasks— the sweep has never executed. Not a security hole (RADD-820 filters expired grants at resolution), but expired rows accumulate forever and the whole TaskSpec pipeline is a dead… -
RADD-874 group.synced is a phantom automation trigger — offered in the catalog, never emitted
automationsgroups· 1 pts ·2164e4a8groups/__init__.py:16registersGroupEvent.SYNCED("Directory group synced") into the event/trigger catalog, but no code path emits it — the sync emits onlyMISSING/RESTORED(groups/service.py:348). Any automation built on the trigger can never fire; the catalog is lying to the rule builder. -
RADD-873 Plugin enable/disable state silently discarded on any boot DB error
pluginmgr· 1 pts ·ed1c9df0pluginmgr/boot.py:26-34wraps the boot-time read ofinstalled_pluginsinexcept Exception: return {}with no logging. The docstring justifies the missing-table case, but the catch swallows every failure — transient DB outage, bad URL, permission error — and answers "no overrides": a disabled plugin silently… -
RADD-876 field_writability runs a dead effective_permissions query on a hot path
fields· 1 pts ·cb481be5fields/router.py:137—perms = await authz.effective_permissions(...)whose result is never used (ruff F841, hand-verified).GET /fields/writableis called byuseItemWritabilityacross the SPA (spec 96), so every issue open pays a wasted permission-resolution round trip. -
RADD-871 Issue page's linked-pages section 404s: SPA calls /items/{id}/docs, route is /items/{id}/pages
itemspages· 1 pts ·2dfdb9abapiItemDocsPath(web/src/lib/constants/api-paths.ts:195) builds/items/{id}/docs, but the backend route isGET /items/{item_id}/pages(pages/router.py:463) since the RADD-701 docs→pages rename.itemPagesQueryis consumed byItemPagesSection.tsxandroutes/item-detail.tsx, so the issue page's linked-pages…
-
RADD-884 Wire the server search/pagination that already exists: audit log, users table, inbox
auditauthnotify· 2 pts ·73824a8dthree surfaces where the server is already able but the SPA never asks: the audit log has limit+offset (audit/router.py:28) but the page hardcodes 200 rows and offers no text filter; Settings → Users has serverqbut no pagination, rendering all 3,088 rows unfiltered; the Inbox caps at 100 with server limit/offset… -
RADD-883 Server-backed q/limit/offset for the big collections; Select flips to server mode at scale
authfieldsgroupslabelsprojectsteams· 5 pts ·99d94ac1client filtering fixes findability but a 2,293-row/teamspayload is the real risk at 10×;/users/directoryships 3,088 rows to every picker. -
RADD-882 useListFilter + ListSearchInput: client-side filter for every settings list
fieldsgroupslabelspagesreleasesteams· 3 pts ·8b7dc8f227 of 47 audited list surfaces have no filter (report 08 table). Worst: Settings → Teams 2,293 rows, Labels 2,016, Fields rail 319 — all fetched fully, so client-side filtering is correct and needs no API change.
-
RADD-901 Kit growth: IconButton, ErrorText, Callout, Popover; useKeyedRows; Modal focus trap; SubjectPicker rebuild
automationssettingsviews· 5 pts ·e88ec5c5Per report 03 §2/§3/§5/§6:IconButtonkills the 34-copy class string;ErrorTextkills 109 ad-hoc error paragraphs;Calloutkills the 9 amber panels;Popover(backdrop + positioning + dismiss-stack) so DisplayMenu/WipLimitMenu/BreadcrumbCrumb stop rebuilding it; the 46 bordered button lookalikes fold into… -
RADD-901 Kit growth: IconButton, ErrorText, Callout, Popover; useKeyedRows; Modal focus trap; SubjectPicker rebuild
automationssettingsviews· 5 pts ·c6efba4dPer report 03 §2/§3/§5/§6:IconButtonkills the 34-copy class string;ErrorTextkills 109 ad-hoc error paragraphs;Calloutkills the 9 amber panels;Popover(backdrop + positioning + dismiss-stack) so DisplayMenu/WipLimitMenu/BreadcrumbCrumb stop rebuilding it; the 46 bordered button lookalikes fold into… -
RADD-881 Select/SelectField grow a searchable mode; TokenMultiSelect caps rendered matches
views· 3 pts ·b93a0c21the kitSelect(Select.tsx:65) only does first-letter jump type-ahead — over the ~1,031-option user directory that is effectively no search. Seven pickers ship it at that scale (issue rail assignee/reporter, New Item, bulk bar, timesheet person, project + team Add member, Jira user mapper), plus…
-
RADD-892 Auth aggregation inversion + kernel entity sockets + project_purge hook
authjiraimportkernelprojects· 8 pts ·d3eeeb8aWhat is wrong (report 01 §1/§2/§4): auth imports six feature modules it outranks (nav-facts from timelogging/forms, PageSpace scope labels, groups/teams subjects) — the aggregation inversion;kernel/entities.pyhard-imports auth/projects/events at runtime;jiraimport/rollback.pydeletes seven modules' tables by… -
RADD-891 Setting keys become SettingSpec contributions; settings keeps the cascade mechanism
kernelsettings· 5 pts ·d560ca97settings/types.py::SettingKeyhardcodes AI (7), CSAT, release (2), timesheet (4), LDAP (12), workflow and estimation keys — the settings module knows every feature's tunables; the file calls itself a registry but is an enum (report 01 §5). The kernel plugin fields for this (settings_keys) exist and are never read… -
RADD-890 Permission atoms become RaddPlugin contributions; auth keeps only its own
authkernel· 8 pts ·f249d484auth/types.py::Permissioncentrally enumerates ~150 atoms for every module while the kernel permissions registry exists and milestones proves contribution works — two parallel systems, and every new module edits auth (report 01 §5, critical). -
RADD-902 Split the oversized security-critical files along their own section markers
aiauthautomationsviews· 5 pts ·275fe9c1Per report 02 file-size table + report 03: 65 backend / 64 frontend files exceed the ~300-line rule. This issue takes the ones whose seams the reports verified:auth/authz.py1099 (decision core / seam / batched / explain),auth/service.py1087 (users / sessions / tokens / lifecycle.py for the merge-delete block),… -
RADD-897 One clock, tunables into config.py, db pool settings
kernel· 2 pts ·179c66e8Per report 02 systemic fixes 2/6:radd/clock.py::utcnow()(naive-UTC, documented as the schema convention) replaces the 15 private_utcnow/_nowhelpers and ~15 inline copies; normalizetimezone.utc→UTC(attachments/movejob.py). Tunables sweep: sso/forgejo httpx timeouts, the stray BATCH/MAX_* module… -
RADD-895 Backcompat removal, server side: alias routes, dual-shape parsers, wire mirrors, one-shot migrations
aiattachmentsauthcommentsfieldsforgejoldapreportingssoteamsviews· 3 pts ·8a9923d2Per06-backcompat-hacks.mdand the no-backcompat-until-V1 rule: delete the pre-102 attachment alias routes (A1), the Forgejo env-state merge fallback + env-keyed capability check (A2/A3 — capability counts connection rows instead), theUserSource.UNKNOWNlazy upgrade via one throwaway migration deriving source… -
RADD-900 Semantic status color tier; charts and roadmap consume tokens instead of hex
dashboardsreporting· 3 pts ·a06793faPer report 03 §1 + systemic fix 1: charts still draw the retired indigo accent (BURNUP_SCOPE_COLOR/CHART_ACCENT_COLOR#818cf8) and stock-zinc grid/axis hexes, theme-blind; roadmap connectors same; cycle pills use shades absent from the light remap (blue-200 on white ≈1.4:1); kind/priority icon shades unmapped; the… -
RADD-893 Backend dead-code sweep (~1,100 lines): RADD-828 cluster, spec-90 schemas, kernel dead seams, 12 routes
authbackupformsjiraimportkernelpagessso· 3 pts ·b7f5ae23Per05-dead-code-backend.md, the CERTAIN/LIKELY deletions: the RADD-828 cluster (if-False branch, deflect_public, Form.public_token + drop migration), spec-90 wizard schemas + ImportStage enum, the sso identity surface, 37 dead functions, the never-wired kernel machinery EXCEPT TaskSpec (which RADD-872 wires… -
RADD-898 Enum-bypass fixes + exception narrowing + the lints that keep both fixed
aiattachmentsauthautomationsmcppluginmgrworkflow· 3 pts ·4d2dfca7Per report 02 §1/§2: use the enums that exist (RuleType in the routing engine, ApproverKind in guards, InstanceRole in roles_router, ItemEvent.DELETED in comments/attachments parents, StorageHostType in backup); new enums where the vocabulary lives in a comment (automations PlanKind, embedder EmbedTaskKind, pluginmgr… -
RADD-889 MCP core tools become McpToolSpec contributions in their owner modules; pages_bridge dies
itemsmcppagesreleasestimelogging· 5 pts ·a843098fthe RADD-640McpToolSpecregistry has exactly one client (milestones); the 19+ core tools are hardcoded inmcp/tools.pyimporting ten modules, andpagesis special-cased through an importlib reflection bridge (pages_bridge.py) that duck-types signatures at runtime (report 01 §5). -
RADD-896 Backcompat removal, frontend: pre-101 tolerance, legacy queue path, legacy routes decision
editorviews· 1 pts ·c8890350Per06-backcompat-hacks.md(d) +05-dead-code-frontend.md§3: makefeaturesrequired in the AI status type (the SPA and backend ship in one image — no pre-101 pairing exists), delete ViewList's unreachable legacy queue render path (QueueRowMeta + prop threading; confirm no swimlane reuse), fixapplyRankChain's… -
RADD-894 Frontend dead-code sweep (~660 lines + 5 assets): query factories, meta constants, types, CSS
jiraimportpagesviews· 2 pts ·50a10999Per05-dead-code-frontend.md: the query-factory + queryKeys + api-path chain (~170 lines, one refactor's residue), six meta.ts constants, the misc dead exports (useMoveItem, EpicProgressBlock, plugin-loader diagnostics, …), 16 dead types incl. the pre-spec-100 jira-import block, dead zinc tokens + the stale… -
RADD-870 Docs truth pass: doc-file drift (CLAUDE.md, modules.md, contributing, README, PLAN)
docs· 3 pts ·eabc0dfdWhat is wrong (report 04): CLAUDE.md's status preamble is 12 releases stale (claims 0.9.0; newest tag v0.21.0), cites a/healthendpoint that does not exist, a--workspace mainimport flag that argparse rejects (also in README), "Tests 1335" (now 1570). docs/modules.md: pgvector listed as an unbuilt gap (shipped… -
RADD-899 Snapshot[T] TTL helper replaces the four module-level write-through caches
aiattachmentssso· 2 pts ·daf6a603Per report 02 §7: sso registry_snapshot, ai_role_snapshot, attachments hosts_default_snapshot+ clients_cache, and the SSO metadata cache all go stale under >1 web replica (admin edit in worker A, worker B serves old state until restart). OneSnapshot[T]helper (value + loaded-at + ttl + async refresh,… -
RADD-887 Model-import burn-down: access read seams, ldap→groups.service, forms portal, notify, search, misc
accessaiapprovalsformsldapnotifypagessearch· 5 pts ·14d858a2the report-01 §3e/§3f reaches: four access-framework adopters queryAccessGrantdirectly (dashboards/fields/views/pluginmgr);ldap/groupsync.pywritesgroupstables raw;forms/requests.pycomposes five modules' tables;notifyimports a comments-internal visibility helper;search/semantic.pyreads… -
RADD-888 SLQ relational builtins move into owner SlqFieldSpec contributions
cyclesitemsitemtypesreleasesteamsworkflow· 5 pts ·485d4598spec 97 builtSlqFieldSpecso "items never learns those modules exist", then left the builtin catalog hardcoded —items/slq/builtins.py:12-16imports cycles/releases/itemtypes/teams/workflow models whilelogged_by/commented_bygo through the registry (report 01 §3a). -
RADD-886 events.service re-exports Event; the 13 consumer imports of events.models die
events· 1 pts ·16cf0aeftheEventrow IS the consumer contract, but it lives inevents/models.py, so 13 consumers import another module's models (report 01 §3c list). -
RADD-885 CI ratchet: models-import whitelist + imports⊆depends_on, with weak_depends on RaddPlugin
kernel· 3 pts ·a5ee9fa6the written spine exception (User, Project) is fiction — 78 non-spineX.modelsimports, 30 modules importing undeclared deps, cycles hidden behind "# deferred: loads after" comments (report 01 §3/§6 tables). -
RADD-863 Deep-scan audit 2026-08: nine-category codebase report
docs· 3 pts ·14c26b4dWhat: Full deep scan of the codebase (~76k lines Python / ~78k TS) across nine categories: kernel/plugin architecture violations, backend + frontend bad practices, misleading docs/comments, dead code (both sides), backcompat hacks, missing features, and the long-lists-without-filters sweep Hussein flagged.
Changes from v0.21.0 to v0.22.0.
Mirrored from project.radd-hq.com on 2026-09-12. Documentation is written there; this copy is regenerated by scripts/publish_wiki.py and hand edits do not survive it.
-
Developer guide
- Architecture: the kernel and plugins
- Develop, test and deploy
- Events and consumers
- Permissions and access control
- The MCP server
- The query language for developers
- The REST API and authentication
- Write a backend plugin
- Write a page editor extension
- Write a plugin user interface
- Write an automation node
-
Release notes
- 0.36.4
- 0.36.3
- 0.36.2
- 0.36.1
- 0.36.0
- 0.35.0
- 0.34.0
- 0.33.0
- 0.32.0
- 0.31.1
- 0.31.0
- 0.30.0
- 0.29.0
- 0.28.0
- 0.27.0
- 0.26.0
- 0.25.1
- 0.25.0
- 0.24.1
- 0.24.0
- 0.23.1
- 0.23.0
- 0.22.0
- 0.21.0
- 0.20.0
- 0.19.0
- 0.18.1
- 0.18.0
- 0.17.2
- 0.17.1
- 0.17.0
- 0.16.0
- 0.15.0
- 0.14.1
- 0.14.0
- 0.13.1
- 0.13.0
- 0.12.0
- 0.11.0
- 0.10.0
- 0.9.2
- 0.9.1
- 0.9.0
- 0.8.1
- 0.8.0
- 0.7.1
- 0.7.0
- 0.6.6
- 0.6.5
- 0.6.4
- 0.6.3
- 0.6.2
- 0.6.1
- 0.6.0
- 0.5.0
- 0.4.1
- 0.4.0
- 0.3.2
- 0.3.0
- 0.2.0
- 0.1.0
-
User guide
- AI features
- Attachments
- Automations
- Cycles and releases
- Instance settings
- Intake forms and the portal
- Notifications and the inbox
- Personal settings
- Project settings
- Projects
- Reports and dashboards
- Search and the query language
- Start here
- The application window
- The card designer
- The roadmap
- The service desk
- The wiki
- Time logging and the timesheet
- Views
- Work items