Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write a design for the possible solution #50

Closed
sayanarijit opened this issue Oct 10, 2021 · 12 comments
Closed

Write a design for the possible solution #50

sayanarijit opened this issue Oct 10, 2021 · 12 comments

Comments

@sayanarijit
Copy link
Owner

sayanarijit commented Oct 10, 2021

Write a design for the possible solution we came up with in #49.

Ref: #46

@sayanarijit sayanarijit changed the title Write design goals for the possible solution Write a design for the possible solution Oct 10, 2021
@sayanarijit
Copy link
Owner Author

sayanarijit commented Oct 12, 2021

Step 1: Capture

Capturing information will be mind's primary focus (as currently is), because
it's the most crucial part, since I can only process information when I capture
them.

When I encounter some information that I want to capture, I don't want to lose
my focus from the current task at hand. Hence, I want the experience to be
as effortless, distraction-free and efficient as possible.

UI/UX

I think mind's current UI design and input mechanism is capable enough.

However, an even cleaner version is possible where I don't see the previously
submitted information. Rather, I only see an input box where I can submit a
paragraph (with details if required) and when I do submit, I get some feedback.

Which means, it's possible to further improve the UI/UX for an even better
experience. So, it might come in handy to allow hacking the UI/UX via some
configuration (and maybe plugin) system.

So, at the core, mind will only provide an interface via which an input
reader can submit information. And a renderer that can render the captured
information.

The input reader and the renderer should be able to receive and acknowledge
live updates asynchronously.

Input reading should have the highest priority and rendering should be
optional.

The information will be submitted in plain text format to keep things simple.
The first line will be considered as the title (required, unique) and the
following lines will be considered as the body (optional).

The input (both title and body) will be raw i.e. no special format, syntax,
metadata or anything that contain some meaning for a tool or algorithm, will be
supported. But I should be free to use my preferred format, syntax or attach
metadata to the information to help me when I visit it later.

The mind CLI tool will come with a default implementation of the input
reader and UI renderer for the terminal, but should be able to run in headless
mode, only exposing the API via different channels, so that other tools can do
the job too.

Sometimes I might want to skip the capture step and go directly to the next step.
For this, there should be easy ways to move the current input to the next step at
every opportunity.

Availability

When I need to capture information,

  • I might not be in the terminal. So, I need a key binding, widget or desktop
    icon to pop open mind in a terminal window whenever I need.

  • I might not be on my laptop. So, a I need a mobile app or widget where I can
    take/forward/share the note and sync via LAN, Bluetooth or some secure
    internet service when I get back to my laptop. The information will get
    deleted from the mobile when mind acknowledges the sync completion.
    It should support manual deletion. But mind should remind me to sync when I
    open it in my laptop after a certain time.
    Bonus: Support voice messages and automatic sync using digital storage
    services.

  • I might not want to install another app just to keep notes temporarily. So, I
    can use an already installed chat service or email or SMS to send the
    information to myself, and later delete it after capturing it in mind.
    But, mind should remind me to visit the apps when I open it in my laptop
    after a certain time.

  • I might be a nerd and use custom IOT devices to capture notes. So, I want to
    be able to implement a custom, self-hosted sync service.

  • I might not have an electronic device at all, and use a plain old physical
    notebook or even my palms to capture information. So, I want to get reminded
    to go through my notebooks and hands when I open mind after some time.

  • I might want to sync from my X app/service automatically, but not sure how.
    So, I want to have some easy way to ask the community.

  • I might want to sync from different projects in different places in my filesystem. So, I want mind to be able to crrate different projects and auto add tasks from the subprojects.

The preferred method of sync/communication will be using websocket because it
has to be real-time.

The information will be captured (queued) as .txt files in a specific directory like /.mind/inbasket, waiting to be processed in the next step. To add some new information to the queue, go to the inbasket directory and enter vim info-$(date -u "+%s").txt.

@sayanarijit
Copy link
Owner Author

sayanarijit commented Oct 23, 2021

Step 2: Clarify

Once I capture enough information that might have some meaning for me, when I
get some free time, I want to go through them and analyze what they really are.

I can delete the information that has no meaning for me. Others are actionable.

For each actionable item, if it's something trivial, I need to finish it right
away. Else, I need to convert them to "Task"s.

I need to prepare well so that I can skip the turning into task step for as
many items as possible.

The tasks could be stored as task-$(date -u "+%s").yml files in the ~/.mind/tasks directory.

UI/UX

The UI will display the information one by one, each for max 2 minutes. I can
either finish it right then or turn it into a "Task".

In any case, I need to mark it as "Done" before the timeout, else it will get
re-stacked and the next item will appear.

In order to turn some information into a "Task" I need to define the following:

  • Expected outcome
  • Steps to take
  • Next step

The information should get auto-attached to the task.

There will be customizable shortcuts to perform actions like making API calls,
auto generate tasks etc.

When the in basket is empty, it will remind me to check other sources like mobile,
notebook etc. whatever I have defined as my in-basket, and provide me an
interface to add adhoc tasks.

@sayanarijit
Copy link
Owner Author

sayanarijit commented Oct 23, 2021

Step 3: Organize

Once I know what to do and how to do, I need to decide if I should and when to
do it. Basically, I need to put the tasks in different baskets. For e.g.

  • Won't do
  • To do by x
  • To do at X
  • To do after X
  • To do with X
  • Delegate to X
  • Others

These can be actual folders inside ~/.mind/tasks.

UI/UX

A bunch of folders. Some will be there by default but can be deleted. Others
can be created. The folders can be ordered by using a prefix numbers. Tasks
can be dragged and dropped from one folder to another folder easily. No sub
folders will be supported. Each folder can contain meta configuration as a
config.yml file inside them. The meta configuration can define properties
like color, tags etc.

@sayanarijit
Copy link
Owner Author

Step 4: Reflect

This is where tasks get priorities based on the 6 horizons of focus:

  • Life
  • Long-term visions
  • 1–2 year goals
  • Areas of focus and accountability
  • Current projects
  • Current actions

The horizons can be defined in different folders like
~/.mind/horizons_of_focus/${num}-${title}.

UI/UX

This step requires maximum visibility to all the tasks that need to be done.
It's basically a dashboard where I can zoom in and zoom out into different
horizons. Every horizon will have a priority set by me. Each item in every
horizon will have a priority set. The dashboard will allow me to define how
critical is the task for each item in each horizon. Then, I'll get the final
priority calculated by an algorithm, also defined by me. Ofcource, I can add
bias points to the task depending on my mood.

@sayanarijit
Copy link
Owner Author

Step 5: Engage

Now that the priorities are defined, it's time to engage and start doing. At
this point I'm sure that whatever I'm doing is the best things I could be doing
right now. There's no pending task or might-be-critical information hiding in
my mind and making me anxious. All I need is the list of tasks to be done.

UI/UX

This is a list of TODOs auto arranged by the calculated priority. All I need to
do is, finish each task and tick it off from the list.

@sayanarijit
Copy link
Owner Author

Let's iterate on the design and try looking from another angle.

@sayanarijit
Copy link
Owner Author

sayanarijit commented Nov 17, 2021

What if we generalise the process and make it implementation independent?

I think we can reduce the whole thing into a simple concept of a version
controlled information-label system.

Let's see how.

Core

The core is the storage that stores information, labels, properties and
revisions, as simple as that.

So, at minimum the core exposes api to:

  • create workspace
  • delete workspace
  • sync workspace
  • import workspace
  • export workspace
  • capture information
  • update information data
  • attach label
  • detach label
  • attach property
  • detach property
    - update peoperty value
  • delete information
  • upload file
  • delete file
  • list information

Information

Information is something we capture, often not knowing what it really is, or
what exactly to do with it. It's just some text data with mime type and revision. After
capturing we will update it, attach and detach labels and properties, until we
have dealt with it and are ready to delete it. That's all the core allows us to
do with it.

Label

As per the core, labels are unique entities (defined as string). The core
doesn't know what or how many labels are there, what they look like or what
they mean. It can only attach and detach labels to information from the given
string.

Property

A property is also something that can be attached to an information. But unlike
labels, which carry only 2 possible states (attached/detached), properties
allow us to attach extra metadata as key-value pairs.

Revision

Each change to the information will contain a revision (basically a UTC
timestamp), so that sync works. Deleted information will have only the id and
revision fields remaining in the DB.

Responsibilities

That's all the core does, i.e. store data. The actual logic will be implemented
by the platform and the user.

Platform

A platform lets the user interact with the storage. But it does a lot more
than that.

Information

The platform knows the format of the information. It also formats the
information before storing. The platform gets to decide what types of data it will
support, and what to do with unsupported data.

Labels & Properties

The platform can define what some labels and properties mean, how they
behave and how they look like. Based on the type of information and the labels
and properties attached to it, the platform can define how to display them and
how users interact with them.

For e.g. A platform can define a label called Pinned, and tell the users
that any information with this label attached will be displayed at the top of
the page with a pin symbol. Or define a property called reminder and tell the
user that information with this property set will behave like a reminder.

Platforms can also let the users define custom labels and properties, and define
how they look and behave.

Revision

The platform can utilise the revision fields to sync data between multiple
devices.

Responsibilities

The platform takes most of the responsibility to allow interaction between the
user and the storage.

The platform can also define or allow the users to define what happens when
some event occurs (e.g. new information, assigned a certain label, deleted a
property) etc.

The platform can also implement support for calender, project
management tools and frameworks etc. but these are not requirements.

The only requirements expected from a platform is to utilise the core storage
system and define everything in terms of information, labels and properties
(except uploaded files if any). And also to standardize the platform
specific meanings of labels and properties so that migration between platforms
are possible without going beyond what the core system allows.

User

Depending on what the platform enables, the user can also utilize the system
to organize and automate organization steps using the platform supported
scripting (code or nocode).

However, it'd be great if the platform allows the users to collaborate and
share their labels, properties and automation scripts to help each other out,
and the users actually do so. Not required, but highly recommended.

@sayanarijit
Copy link
Owner Author

sayanarijit commented Nov 17, 2021

Benefits of the setting explained above:

  • Because the core (storage) is pretty dumb, we can implement it in many different ways (e.g. as plain files and folders, in relational database, in key-value store, nosql etc). We don't need to worry about database availability whether local or remote.
  • Since the platform isn't responsible for storing data for the core logic, it can be implemented in many different systems, as long as the core is implemented for the system and the platform can interact with it.
  • Because most expectations from a platform implementation are optional ("nice to have") implementing a platform is also easy and can support incremental feature implementation.

Drawback:

Most are related.

  • Lack of enforced meaning of labels and properties can cause difficulty in migrating between platforms.
  • Learning platform specifications can be difficult.
  • Customisation of one platform isn't transferrable to another, atleast using the core functionalities.

@sayanarijit
Copy link
Owner Author

sayanarijit commented Nov 17, 2021

Example storage using plain files and folders (git optimized):

/wrksp1/information/123/rev1/data
/wrksp1/information/123/rev1/labels/label1
/wrksp1/information/123/rev1/properties/prop1

@sayanarijit
Copy link
Owner Author

The simplest way is to dump everything in a yaml file like mind already does.

@sayanarijit
Copy link
Owner Author

sayanarijit commented Nov 26, 2021

Standard for labels

A label should confirm to the format: definition::label-parent:label-child.

e.g. plt::pinned, plt::reminder:repeating, plt::pinned:sidebar, usr::work.

The definition:: part denotes where the meaning of the label is defined. Is it defined by the platform (plt::)? Or is it defined by the user (usr::)? If no definition is provided, it will default to usr::.

Now, the actual label can be defined using lower-case, hyphen (-) separated words. Nested labels can be defined using a colon (:) separator.

Standard for properties

Similar to labels, properties also confirm to the definition::property-parent:property-child format and follows the same logic.


This separation of platform and user defined labels is necessary to avoid conflict, where the user means one thing and the platform understands another. For e.g. the word wip might mean that the task is "work in progress" to the platform, but might also mean it's a "wise individual's principle" (something I made up) to the user. Both shouldn't be mixed up.

This also makes it easy to migrate from one platform to another without losing functionality, because it will be easy for the migration tools to rename the plt:: labels to the destination platform's equivalent platform defined labels to keep the functionality intact.


We could also introduce std:: to define a standard set of labels that every platform should support, but I think that might be asking too much of the platforms. Also, there will be extra headache to support different versions of the standard.

A better alternative would be to introduce cmm::{community}::{user}::label, where {community} is the name/domain of a community and {user} is the user ID of a member in the community who contributed the meaning of the label. It'd be up to the platforms to support community contributed labels.

@sayanarijit
Copy link
Owner Author

Next: #51

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant