I have an idea
app (legacy category)
Idea type:
29ddb6d5-aa74-5ebb-8bf1-ee684556a9ca
2d97d724-fd45-4168-8c36-f8db6c05cbd0
· Owner: mark@mark-christensen.com
· Created
· Updated
Tags: Data management Human Amplifiers service Tauri
Elements
Optional content — concept, plan, task list, release notes, freeform notes, attachments. Add or edit any of these in any order.
| Type | Title | Pos | Content | Created | Updated | |
|---|---|---|---|---|---|---|
| task_list | Bug: if created in rapid succession, you can create duplicate tags. Saw this on Android but it is likely a race condition on the server, so it impacts desktop too | 0 |
878e5920-5b01-489b-b494-205ef3a6cd38
Data{"done":true}
|
|||
| task_list | Bug: Adding new tasks doesn't change the last edited time? Doesn't seem to. Not sure if this is only Android or if it is true on Desktop too. | 0 |
6f8572a8-6f59-4fd9-8e06-ba3fdfaa2714
Data{"done":true}
|
|||
| task_list | Bug: View time is never updated on Android? It always shows never viewed. Also, new Ideas don't get a viewed time in Desktop even though the user automatically is shown them when it is first created. The viewed time should be set at the same time. | 0 |
9220e2f7-8ab2-4583-9270-79bb7771a92a
Data{"done":true}
|
|||
| plan | Main development | 0 |
2427bffd-062a-42b6-b77b-9e82f1ddcba3
Data{"complete":false,"items":[{"children":[{"children":[],"done":false,"id":"894b5405-796a-46c3-8330-dfb586bd4196","ref":{"element_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","kind":"release"},"text":"0.12"},{"children":[],"done":true,"id":"12f877ab-a413-43c9-9e14-b8f4facb8a80","ref":{"element_id":"981fb916-2577-4aa3-8f86-fe0c31198898","kind":"release"},"text":"0.11"},{"children":[],"done":true,"id":"80108e9c-9a3f-448a-841f-d61e7bc19bdd","ref":{"element_id":"e3ecc6a3-069f-4a8f-907e-e0b6d2e8908a","kind":"release"},"text":"0.10"}],"done":false,"id":"a7f5cebc-fda9-4ec9-b481-dc220f96d06a","ref":{"element_id":"c7436b58-7978-4418-a0e2-354028273d51","kind":"release"},"text":"1.0"}],"schema":2.0}
|
|||
| task_list | Bug: [Desktop+Android] Shouldn't be able to go "back" while editing something like notes or a plan without a confirmation modal | 0 |
c920f761-70c8-4038-a449-1f71789c2e7b
Data{"done":true}
|
|||
| task_list | UX: Adding items to plans or saving plans is hard on Android because the virtual keyboard covers them | 0 |
8e85d31c-c5ab-4799-9fea-850bf541be87
Data{"done":true}
|
|||
| task_list | [Desktop+Android] Trim whitespace from user input for all fields (tags, notes, etc) | 0 |
17777ffa-0a5e-4121-bcb5-a25cf572fceb
Data{"done":true}
|
|||
| task_list | Bug: [Android] can't delete tags | 0 |
8188ef84-6a15-4f78-848d-a7f0234e8c6e
Data{"done":true}
|
|||
| task_list | Bug: [Android] The virtual keyboard covers the bottom content on the screen (whichever screen the user is on) making it impossible to access/see some things. Also, it pushes up the content a bit, so the user also can't scroll to the top of the view (if it's tall enough to go off the screen) | 0 |
40383746-c57e-46d5-ab08-932466378f06
Data{"done":true}
|
|||
| task_list | UX: Tasks being limited to a single text input sucks. It should expand to a larger text area if they type enough | 0 |
6728b68f-8eea-4dc7-8390-c41f22b053eb
Data{"done":true}
|
|||
| task_list | UX: Clicking on a task that is longer than the visible space (if it's truncated) should first expand it so it's all visible. Only when it's full visible should it switch to edit mode on click. | 0 |
5d5dcaa5-4ec9-420d-a1a5-196213c8dbf3
Data{"done":true}
|
|||
| task_list | Bug: [Android] Releases not showing in the UI. They say they are saving but they don't show | 0 |
33edc2ee-1d59-4c8f-b187-9c5a1e50ed49
Data{"done":true}
|
|||
| task_list | When the server restores, it should communicate that to the clients in the next update. in that case, the client should try to rectify its events with the server without deleting events that happened later in time than the restored server data (i.e. it shouldn't ever lose data the client has even if the server rolls back) Feature | 0 |
14bb975c-5732-4788-b7a4-f5470793b040
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | Service: Add viewer for API errors Feature | 0 |
187410e3-b2c6-4d36-8c13-81ea28c37d3e
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| release | 1.0 | 0 |
c7436b58-7978-4418-a0e2-354028273d51
Body (132 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"First \"finished\" version"}]},{"type":"paragraph"}]}
Data{"released":false}
|
|||
| task_list | Bug: Android sync causing 500 error | 0 |
956f4d49-6a96-49f5-bdfb-66711a23752c
Data{"done":true}
|
|||
| task_list | Bug: [Android] Can't add new tasks on the task list page | 0 |
7ec9f857-d534-4664-8986-a5f4ba540a47
Data{"done":true}
|
|||
| task_list | Several fields for an idea don't show when viewing it on the admin console. The entire Idea should be visible | 0 |
ecdd2b28-fef5-41f6-b012-4fada0717838
Data{"done":true}
|
|||
| task_list | Mobile doesn't have a way to backup/restore it's sequence of events | 0 |
3b94a659-478b-4791-b660-47fec743bf12
Data{"done":true}
|
|||
| task_list | Bug: Sync is broken due to an invalid field type varchar(255) instead of text, accessed when running CrdtApply.apply_element_upsert | 0 |
9ec5dddb-16d0-48f7-8f83-14377447562a
Data{"done":true}
|
|||
| task_list | feature: export all not-done tasks to a simple, ordered list to make it easier to feed to an LLM | 0 |
302e86ac-ff52-48cb-aee5-5c9e55d3eeef
Data{"done":true}
|
|||
| task_list | Add real user Auth. First version should just be password but later maybe add magic link login | 0 |
c92bdf89-095d-424b-a12f-cffb92e15027
Data{"done":true,"release_id":"e3ecc6a3-069f-4a8f-907e-e0b6d2e8908a"}
|
|||
| release | 0.9 - Core functionality | 0 |
26a6251a-c1aa-4dc1-9671-b0616e19c6e2
Body (155 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"All the basically functionality and release builds for each component."}]}]}
Data{"released":true}
|
|||
| task_list | UX: [Android] Toolbar painted over top of text area instead of above it. This cuts off the top of the view | 0 |
64c24537-6984-4087-88e6-7015dfeeede4
Data{"done":true}
|
|||
| task_list | Feature: Tie tasks and releases to plans | 0 |
f9a59a5a-9e7a-47ae-9935-f3ce226e79a6
Data{"done":true}
|
|||
| task_list | Feature : Task types - bug, UX, feature, etc. | 0 |
24483e27-94d8-4cc4-8382-e783b47fac85
Data{"done":true}
|
|||
| task_list | Bug: [Android] multi-line edit view broken again. It always shows editing as a single line. | 0 |
22eec89e-fe2f-4152-bbc5-f8e4f9f36040
Data{"done":true}
|
|||
| task_list | Feature: Idea types - different types have different blocks (e.g. a house project doesn't need the linked repo block). Start with types "software" which has all the existing blocks (hardcoded for all users). Provide a way for users to define their own idea types and select which blocks are included. But any idea should also be customizable to add/remove blocks (e.g. a software project defaults to having linked repos but the user could create a new software idea and then remove that block for that idea); the normally associated blocks with an idea type are just what a new idea of that type starts with, they aren't mandatory. | 0 |
f4834656-b6eb-4f83-8760-84bae6f4f924
Data{"done":true}
|
|||
| task_list | Feature: Activity tracking for an idea. Some way to summarize how much changes is happening on a project. Just a sparkline? | 0 |
46c2bb1f-762b-4d65-ba5d-9fe7f55bb6d9
Data{"done":true}
|
|||
| task_list | Feature: Download page (part of the admin service) that requires a unique invite code. Code generated by admin ("create download link"). If provided code is invalid, it shows a generic "in closed beta" message. When valid, the page shows all the download options (i.e. right now that's Windows desktop app and Android mobile app) | 0 |
3cbb9a06-162c-4bcd-8e16-025fe639df2b
Data{"done":true,"release_id":"981fb916-2577-4aa3-8f86-fe0c31198898"}
|
|||
| task_list | Maybe - seems like CPU spikes a lot on the API server during an initial sync, even if there isn't a ton of data to transfer. Needs investigation Bug | 0 |
2add5097-3884-41b6-b080-91fc6139ca8d
Data{"done":false,"task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | Feature : Check for updates for Android. Checks if there is a new version and gives the ability to visit the download page to get it (needs to generate a valid link for that user to download) | 0 |
6d3ad759-4dfc-423e-9217-598ea1428fc1
Data{"done":true}
|
|||
| release | 0.11 | 0 |
981fb916-2577-4aa3-8f86-fe0c31198898
Body (111 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Downloads from the service"}]}]}
Data{"released":true}
|
|||
| task_list | Expand/collapse items on the plan. When all the subitems for an item are marked done, the subitem list is collapsed. Icon (somewhere) to exoand/collapse the list of subitems. Can't interfere with current functionality Feature | 0 |
38dc19bb-56f5-400d-bf26-d96d7717fce3
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | Add more default idea and task types Feature | 0 |
d1080556-5b2a-4792-a71a-c16b22aadcdb
Data{"done":false,"release_id":"c7436b58-7978-4418-a0e2-354028273d51","task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | User custom blocks. Content type for blocks is fixed but user can create "custom" blocks (really just renamed block type instances) Feature | 0 |
61d01178-1091-4622-8a23-97a62289ebc0
Data{"done":false,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | If plan item has subitems, it always shows the done percentage, even if it's 100% UX | 0 |
22b239be-2963-4f41-a0a2-2d3272cd2297
Data{"done":true,"release_id":"c7436b58-7978-4418-a0e2-354028273d51","task_type_id":"a57ca2a4-d396-587e-b1bb-1615090d015a"}
|
|||
| release | 0.12 | 0 |
6697102c-1c21-4384-85a8-f7b8872d2f1c
Body (98 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Custom blocks"}]}]}
|
|||
| concept | 0 |
2d8e98be-eb60-428e-ad6f-c43355ecb8b3
Body (242 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Keeps track of any kind of ideas for things you want to do something with in the future. Maybe it's a project, something to build, a story to write, anything"}]}]}
|
||||
| task_list | Favorites - Ideas that are pinned and easy to access Feature | 0 |
568f536e-699d-4281-b50f-5a107a381825
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | GitHub-style idea visualiser. Like the sparklines but tracks across all ideas and is visualized as a daily heatmap Feature | 0 |
684dfccb-1b78-4d9b-bbb7-ddb9a90ac2c3
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | Download links expiring too fast. Bug | 0 |
fd2522e8-5c53-4d7f-bec0-eecdc4ed6a94
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | Edit history for any item, based on CRDT list Feature | 0 |
2e9c620c-7f65-46c9-8131-a149c26117cc
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | Add idea "status" which shows at top of edit and on list page. Example status: idea (initial status), in progress, paused, ready! Feature | 0 |
963a87e3-aea2-42a1-96f8-575368e94472
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | Add plan "complete" status (like with tasks) Feature | 0 |
ffc6fa82-6f3b-439d-acf8-28e2b254d04e
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | "editing arrives in a later phase" placeholder for concept is incorrect Bug | 0 |
9f70d3e5-939a-4a1e-ac44-93bd17b5b0d5
Data{"done":true,"task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | Add export/import for desktop app Feature | 0 |
0aca2999-804b-464e-a3b4-6f3eb47e9830
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | Tasks and other completeable items shouldn't move location in their display list when they are marked as done UX | 0 |
4541e3dd-5710-4a7f-9767-d9381cbde09b
Data{"done":true,"task_type_id":"a57ca2a4-d396-587e-b1bb-1615090d015a"}
|
|||
| task_list | Tasks need an "add to release" feature Feature | 0 |
e9355b21-44bd-4561-aee2-ae80d9c576de
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | Fix task creation UX everywhere. Instead of a single input field, it should be a modal UX | 0 |
b5a51c2f-4cc5-4760-bcdd-41e6c405c075
Data{"done":false,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"a57ca2a4-d396-587e-b1bb-1615090d015a"}
|
|||
| task_list | Start tasks expanded in the list view and add expand all/collapse all to any list of tasks (not counting plan view) UX | 0 |
c5178a21-78a6-4910-a620-3b1ebc0ca9ae
Data{"done":false,"task_type_id":"a57ca2a4-d396-587e-b1bb-1615090d015a"}
|
|||
| task_list | change sparklines to 30 days UX | 0 |
a1c1fe09-5b00-4f0d-b0ee-03ad6f9fe418
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"a57ca2a4-d396-587e-b1bb-1615090d015a"}
|
|||
| note | Inspiration/Influences | 0 |
a3e0f100-fe89-4e99-9d7c-c9cf5a5f605d
Body (443 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"UI/visual style/design"}]},{"type":"bulletList","content":[{"type":"listItem","content":[{"type":"paragraph","content":[{"type":"text","text":" "},{"type":"text","marks":[{"type":"link","attrs":{"href":"https://github.com/scastiel/kado","target":"_blank","rel":"noopener noreferrer nofollow","class":null,"title":null}}],"text":"Kado"}]}]}]},{"type":"paragraph"}]}
|
|||
| task_list | Like "attachments", add a new type which is just URLs (tagged, labeled) Feature | 0 |
dd50915d-8d7c-43d6-8b89-0562a54f540b
Data{"done":false,"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | UI/UX issue - can't change bold or italic status when there is no text (or it changes and the UI doesn't show the change) Bug | 0 |
5d9107ab-a472-4108-8afb-239419246ca5
Data{"done":false,"task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | UX: In the task count widget (next to the "Tasks" header) it should show only the count of undone tasks. The "Show done" action should also be changed to include the count of done, like "Show done (47)" but with a cap of 99; if larger then 99, it should say "Show done (99+)" | 23 |
3ebac1cc-d6f1-40ed-98dd-a84fd8f50c47
Data{"done":true}
|
|||
| release | 0.10 | 32 |
e3ecc6a3-069f-4a8f-907e-e0b6d2e8908a
Body (110 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Add passwords for syncing"}]}]}
Data{"released":true}
|
|||
| task_list | Download link creation isn't adding the label (it's always blank) Bug | 41 |
4daca6e8-2e42-48c4-82e7-41243dabe5d3
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | Tasks aren't getting counted towards completion rates for their parent item on the plan Bug | 46 |
774c3aeb-9715-4411-ad87-8f1d625623f2
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | Creating a new task from the plan doesn't work to set the type. It just makes it no type Bug | 47 |
b173afb0-2ea2-4473-9434-69e435dea49f
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | Task search should be treated as a series of keywords. The search done should add wildcards between the words (split on spaces). Ideally, it would match any order of those words too Feature | 48 |
a83540f3-9531-4945-9c58-f72b76a162e3
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| task_list | When making a new plan, can't add existing releases. Requires at least one entry on the plan before search finds them successfully Bug | 49 |
a9b790df-d1c6-47f5-8aae-41322de64079
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"818ca193-82c3-5d3d-8976-2b0b8359226f"}
|
|||
| task_list | Change build process for Windows to create signed exe (see notes) Feature | 62 |
4d2b676c-63fa-46ac-a301-4950592149b9
Data{"task_type_id":"83776309-6f31-52b1-89ab-fce3a072eef9"}
|
|||
| note | Signing EXEs on Windows | 63 |
7645faa6-10da-4200-a5aa-78147f99364b
Body (1439 bytes){"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"If an app isn't signed, it will be flagged as malware by Defender, Avast, and other AVs. It needs to have a certificate associated with it. The obnoxious thing is that they are sold through "},{"type":"text","marks":[{"type":"link","attrs":{"href":"https://www.digicert.com","target":"_blank","rel":"noopener noreferrer nofollow","class":null,"title":null}}],"text":"Digicert"}]},{"type":"paragraph"},{"type":"paragraph","content":[{"type":"text","text":"Tauri docs "},{"type":"text","marks":[{"type":"link","attrs":{"href":"https://v2.tauri.app/distribute/sign/windows/","target":"_blank","rel":"noopener noreferrer nofollow","class":null,"title":null}}],"text":"here"},{"type":"text","text":" ("},{"type":"text","marks":[{"type":"link","attrs":{"href":"https://v1.tauri.app/v1/guides/distribution/sign-windows/","target":"_blank","rel":"noopener noreferrer nofollow","class":null,"title":null}}],"text":"for v1"},{"type":"text","text":")"}]},{"type":"paragraph"},{"type":"paragraph","content":[{"type":"text","marks":[{"type":"link","attrs":{"href":"https://www.digicert.com/difference-between-dv-ov-and-ev-ssl-certificates","target":"_blank","rel":"noopener noreferrer nofollow","class":null,"title":null}}],"text":"Difference between cert types"},{"type":"text","text":" (EV is the best but OV probably makes the most sense for Human Amplifiers)"}]}]}
|
|||
| task_list | Improve idea status filtering UX - Filter is permanent and select-many, not select-one UX | 64 |
b88459ae-2070-4489-9a65-eaf83756ee61
Data{"done":true,"release_id":"6697102c-1c21-4384-85a8-f7b8872d2f1c","task_type_id":"a57ca2a4-d396-587e-b1bb-1615090d015a"}
|
Shares
Granted from the desktop or Android app's Share dialog — this view is for oversight/cleanup, not for granting new shares.
| Access | Status | Created | Updated | ||
|---|---|---|---|---|---|
| Not shared with anyone. | |||||
Linked Repos (Assets)
Read-only here — repos are linked and scanned from the desktop app, then synced to this account.
| Repo | Remote | Last Commit | Scanned | Details |
|---|---|---|---|---|
| ihaveanidea | git@144.76.119.114:/home/git/ihaveanidea.git |
3aebfdea 0.11.7 - Added completion for release and plan. Fixed a few UX bugs.
|
All fieldsID:
60b7deba-97a2-4667-829a-b1c6cfb6a17aLabel: Primary
Local path:
C:\Users\anonymous\projects\ihaveanideaDefault branch: main
Last commit author: anonymous <anonymous@anonymo.us>
Last commit at:
—
AGENTS source file: AGENTS.md
Source device app id:
desktop:38ded643-95fb-489f-969c-7871359f7c40Created:
Updated:
README excerpt (2016 bytes)# ihaveanidea Track project ideas — software, physical-world, writing, anything — from a quick elevator pitch through implementation and "release." ## What It Does - **Ideas** are the top-level thing you track. Creating one only requires a **name** and a short **pitch** — the "spark" moment. - **Elements** are optional content you attach to an idea over time: a concept/spec writeup, a plan, a task list, release notes, freeform notes, attachments. There is **no enforced lifecycle** — elements can be added, edited, or skipped in any order. Presence of elements is the progress signal, not a status field. - **Category** is a free-form tag (e.g. `software`, `physical`, `writing`, `other`) — never a fixed enum. - **Assets**: the desktop app can link an idea to a local folder/git repo and extract metadata (repo name, remote, last commit, README/AGENTS excerpt). That metadata syncs to the account so it's visible read-only from the browser admin and Android, even though only desktop can see the filesystem. - **Local-first** desktop and Android apps sync with the service when connected, using the same CRDT-log approach as the reference project below. - **Single user** — this is a personal tool, not a multi-tenant product. ## Key Decisions ### Architecture | Decision | Choice | |----------|--------| | **Primary data store** | The service (Phoenix/Elixir) | | **Sync model** | CRDT-style whole-record last-write-wins upserts; operations stored for audit log | | **The service** | Single Phoenix codebase; API and admin run in separate Docker containers for independent scaling | | **Lifecycle model** | No status/stage FSM — ideas accumulate optional typed elements in any order | | **Build isolation** | Each component (service, Desktop, Android) builds independently — no shared-code package | ### Technology Stack Mirrors the sister project [panoptodo](../panoptodo), which this project's stack and repo conventions were deliberately modeled on. | Component | Stack | |--------- AGENTS excerpt (931 bytes)# Repo-wide conventions This repo holds multiple independently-buildable components (`service/`, `desktop/`, `android/`). See [service/AGENTS.md](service/AGENTS.md) for Phoenix/Elixir-specific guidelines. ## Cross-cutting rules - **Mix always runs inside Docker.** There is no local Elixir/Erlang toolchain on the dev machine. Never run `mix` directly on the host — use `docker compose --profile tools run --rm mix <task>` from `service/`. - **Changelog discipline**: add an entry to `CHANGELOG.md` for every significant change, using the actual current date (YYYY-MM-DD) and the project/app version scheme described there. - **No shared-code package** between `service`, `desktop`, and `android`. Keep `PROJECT_DEFINITIONS.md` current — it is the mechanism that keeps the three independently-implemented clients consistent with each other. - **Commit messages**: concise, imperative mood, focused on why a change was made. |