@ibgib/ibgib

0.0.148 • Public • Published

🚧 vcs prototype coming 🔜

ibgib version control projected release schedule:

alpha:

September, 2024

beta:

May, 2025

1.0:

July, 2025

ibgib - the protocol, the rcli, the version control

Ibgib is a novel protocol that enables data-centric distributed computation by focusing on space and time as its primary first-class citizens. It is literally spacetime in the actual code. This spacetime acts much like a version control system but for all code, data, metadata, and derivative data.

This approach has far-reaching consequences too numerous to list here. It is not blazing fast, but it is genuinely, innovatively mind-blowing 💥

Building on this, we will reimagine the CLI as a chat among participants, including not only human and ai identities as participants, but also the app itself as one. We will move from a command-only line interface to a request/command line interface: the RCLI.

Now each of these participants is represented by the same ibgib data semi-structure. When you go to edit a profile or update an ai model, you update its timeline. When you go to update the profile of the app, you update its timeline. And the derivative data each produces uses this same shape. Every comment, link, pic, file...whatever data it is, each one is an ibgib and each has its own timeline.

All code, data, metadata, derivative data...all of it -- it's all about space and time. Literally. This is not market speak. It's literally domain logic that enables a biologically-inspired meta language.

Just think of your entire devops workflow. Source control itself is the first step to devops (it doesn't start after that). Your facility with source control is your introduction to a language-agnostic metalanguage. And recently we've grown accustomed to just tacking on more language ad hoc that all do the same thing: package management, reproducible builds, containerization, deployment configuration, infrastructure-as-code. This is all about space and time: where do we put the things and how do we version them.

As such, your initial introduction to ibgib will be via the more familiar special case of a source-code Version Control System. On the one hand, this will help ease you into the concepts since most software-related creators are well-acquainted with version control dynamics. But also, I just need the damn thing in order to version control the ibgib protocol itself.

tl;dr

throw new Error('tl;dr not implemented. (E: 6f2bec54bebb4fb8856445416a7712ec)');

quickstart

Ibgib is new. There is NOTHING like it. Git's repo+branch design is kinda like it. IPFS's Merkle forest+IPLD+Ceramic+IPNS design is kinda like it. Tim Berners-Lee's Solid Pods RDF triple design is kinda like it. Some other DLT-based designs are kinda like it. So if you're familiar with any of these, you're not starting completely from scratch.

But really, there is nothing like it. But if you feel that burning urge to start quickly, skip all the blah blah English, run the commands and check your output against the expected output.

getting started - version control

This is the guide to getting started with this alpha version of ibgib. As stated, ibgib itself is a protocol that enables a new distributed computation approach based on two first class citizens: space and time.

So oddly enough, we're talking about the spacetime continuum. And so I call this version control system Back to the File System, because we're going all the way back to the 50s (1955?) when the concept of the "file" system was first introduced.

Files are no longer our storage of data. The new storage concept is ibgib. What are ibgibs? For now, let's just say that they are timelines. The ibgib is a semantic unit that after a change, either intrinsic or extrinsic, it's still the "same" ibgib. In most cases, these by default monotonically increase, just as some version control systems "never" delete old versions.

Practically speaking, the key thing to remember here is that a file is not "just" a file, it is a timeline. A directory/folder is a timeline of timelines. Any group of "files" is a projection of timelines. We will be using the terms files, folders/directories, but always keep in mind these are aides in transitioning away from arbitrary file- and repo-level granularity.

You have to think 4th dimensionally, Marty!

step-by-step

Let's go through these steps with an example project that we'll start off calling a repo. I am going to do this as a test run for ibgib's own codebase, but I recommend you just make a new contrived repo and add some files/folders as you like.

install via npm

npm install @ibgib/ibgib@latest --global

note: all packages are scoped with @ibgib to help reduce name confusion attacks. @latest is included because I'm constantly updating right now.

Navigate to your project's directory and initialize the ibgib RCLI. Here we provide the --space-name to identify its concrete location (in addition to differentiating it from a vcs branch space that we'll create in a future step).

When prompted, just hit ENTER to accept/confirm the defaults.

ibgib init --space-name='local_laptop_my_project'

my-project$> ibgib init --space-name='local_laptop_my_project'

Expected output:

Here is a summary of what we did:
0) initialized metaspace: /home/wraiford/my-project/.ibgib
1) initialized first local space: witness space NodeFilesystemSpace_V1 local_laptop_my_project b7a955c791257263635ccd80f21e8cc7c7adf90ad8ede41aa6b8c86655b6f838 undefined undefined
2) initialized multiple apps. chat_gib, raw_gib, todo_gib, RCLIApp_V1_misoixqn
3) initialized robbot ibgib: Rolly

note: from this point forward, to simplify copy/paste commands, I will exclude the prompt my-project$> unless required. but all of these commands must be entered in the root of the project. otherwise, you must specify a --data-path that points to your data folder which is by default named .ibgib.

So let's break this down.

#0) metaspace

for this guide, we focus on three basic types of spaces: the metaspace, local spaces, and outer spaces.

In step #0, we initialized the "metaspace". Conceptually, There is only one metaspace. This space is responsible for coordinating among one or more local spaces with one or more outer spaces.

#1) local space

Local spaces are those with concrete, local implementations that usually have a relatively lower latency.

The witness space NodeFilesystemSpace_V1 local_laptop_my_project b7a955c791257263635ccd80f21e8cc7c7adf90ad8ede41aa6b8c86655b6f838 undefined undefined is the ib of the local space we just created.

A word on the ib: The ib is one half of the content address of any ibgib. It is a per-use-case metadata field, which is useful because 1) Assuming we've validated the record in some way, we don't have to load the full record for some of the metadata, and 2) This reduces collisions were we to just use raw hashes as content addresses. For now, just realize that ib values are metadata fields, part of the ibgib's address, and have a per-use-case schema.

For our local space, just note at this time three fields:

  • NodeFilesystemSpace_V1 - concrete local space adapter uses a filesystem approach on top of node.js
  • local_laptop_my_project - space name
  • b7a955c791257263635ccd80f21e8cc7c7adf90ad8ede41aa6b8c86655b6f838 - space id
#2) app ibgibs

There is much to say on app ibgibs, but for now the main thing is to think of them as instances of apps - kind of like an app's configuration settings.

The super cool thing is that you can save an app's settings and then propagate those settings using the same mechanism that the version control uses for propagating code.

This is a repeated theme of ibgib's focus on space + time (spacetime) as the primary first-class citizen. If you already have a timeline branching/merging mechanism (i.e. your source code's version control), why create additional complexity when you go to synchronize your app's settings among multiple devices?

The source code is data, the app's configuration is derivative data. You can mobilize both WITH THE SAME DAMN CODE.

#3) Rolly the Robbot

In initializing Rolly the Robbot (two bb's in honor of Robbie), you have initialized the sketchings of a chatbot assistant in our RCLI (Robbotic/Request Command Line Interface). This is not fully fleshed out atow (04/2024), but for now just remember that our goal will be to have a command line that acts essentially as we know and love. Except! We are conceptualizing our command line session as a chat, leveraging this in code, and the fact that the commands go off and execute somewhere, producing derivative side effects dovetails exceptionally well with the rest of ibgib's architecture.

I'll also note that similar to apps, we can move robbots among spaces piggy-backing on the same code (and that this is part of the revolutionary aspect of ibgib).

note: This is not atow (04/2024) transformer/llm-based. But more on AI + ibgib later, but teaser: how are you going to version control your models? Your models' derivative data? How are you going to content address your models' interactions with users? with APIs?...

ibgib b2tfs-init

Now Marty, let's go back to the file system and initialize the vcs.

ibgib b2tfs-init

Expected output:

Created B2tFS Index special index ibgib.

This will be used to keep track of B2tFS roots (roots are kinda like repo mounting slots).

This initializes the B2tFS index but doesn't add any roots or branches just yet.

ibgib b2-info

Before we add a root, let's view our initial B2tFS information:

ibgib b2-info

note: this uses the prefix synonym b2 instead of b2tfs. also valid atow (04/2024) are fs and vcs for any b2tfs commands.

Expected output:

{
  "cwd": "/home/wraiford/ibgib/vcstests/my-project/.ibgib",
  "ibGibGlobalThis": {
    "initialCwd": "/home/wraiford/ibgib/vcstests/my-project",
    "version": "0.0.81"
  },
  "spaceId": "ff1afcffa3f57c471d5fc3920a6ec217ab05243b729f824fbe4cd7fc38c56527",
  "spaceName": "local_laptop_my_project",
  "indexIbGib": {
    "ib": "meta special b2tfs",
    "gib": "5D470BEED54EF0458D3A319A52C2743508DC5AB6416EFF01CFD148237799A076.BF7E15D60227F59B342CE5EBC4A44B2B4D73F0DE73BCC30516674A2E313480B8",
    "data": {
      "n": 1,
      "timestamp": "Tue, 09 Apr 2024 17:14:03 GMT",
      "timestampMs": 138,
      "uuid": "8330dfea74dba9a1a60f3bc2dbbd350ea003074712bce20b134767b0d0fe7551",
      "mySpaceId": "ff1afcffa3f57c471d5fc3920a6ec217ab05243b729f824fbe4cd7fc38c56527",
      "$@branch": []
    },
    "rel8ns": {
      "ancestor": [
        "meta special b2tfs^gib"
      ],
      "dna": [
        "fork^AA9EC524D245236FE2391EE5173F350F9E1932C9F71CD8CE42BDD863E085AEF6"
      ],
      "past": [
        "meta special b2tfs^BF7E15D60227F59B342CE5EBC4A44B2B4D73F0DE73BCC30516674A2E313480B8"
      ],
      "tjp": [
        "meta special b2tfs^BF7E15D60227F59B342CE5EBC4A44B2B4D73F0DE73BCC30516674A2E313480B8"
      ]
    }
  },
  "indexExists": true,
  "indexAddr": "meta special b2tfs^5D470BEED54EF0458D3A319A52C2743508DC5AB6416EFF01CFD148237799A076.BF7E15D60227F59B342CE5EBC4A44B2B4D73F0DE73BCC30516674A2E313480B8",
  "indexTjpAddr": "meta special b2tfs^BF7E15D60227F59B342CE5EBC4A44B2B4D73F0DE73BCC30516674A2E313480B8",
  "branchInfos": {}
}

This tells us what local space we're using, the B2tFS indexIbGib, whether or not the B2tFS index exists (it does), and some other things. But notice that branchInfos is empty. We need to rectify that.

ibgib b2-branch --input-path=. --add --name=my-project-main

In B2tFS, the paradigm does not include repositories but rather is entirely branch-centric. We do have a project, but since we include all metadata (i.e. the repo config) in addition to the intrinsic data (the files and folders inside of the repos) in the same ibgib data structure, we can interrelate "repos" much more fluidly. This is more akin to symlinks in filesystems, or object references in OOP, but we leverage ibgib's unique spacetime content addressing mechanism. Also similar to a conventional filesystem, if there is no parent branch we call this a root branch (root relative to the local space).

❗ Local spaces and branches (each of which is in its own separate local space in this implementation) are always "local". When we go to send data to other spaces via a sync (or in the future a push/pull), we transfer neither a local_space nor a branch. These are substrate & implementation-specific. The ibgibs that represent the individual timelines of fs files/folders (including the each's entire tree-shakeable dependency graph) are the things that are transmitted.

So let's add a root branch to version control our containing folder. This will add our root branch and create the corresponding B2tFS items that correspond to our files and folders. If you are prompted a confirmation, don't hit anything yet! Just read on...

ibgib b2-branch --input-path=. --add --name=my-project-main

OR we can use the "bare" argument for input-path for this command.

ibgib b2-branch . --add --name=my-project-main

note: right now, only one bare arg is allowed and its use depends in context on the command. The command itself, as we have been using in this guide also does not require a prefix. All other args must be prefixed with a non-word character. I use double dashes so these are what are supported.

Now assuming you haven't cheated and created one, this should notice that you don't have an .ibgibignore file and prompt you with something like the following confirmation:

Expected output:

In your input path (/home/wraiford/my-project) for the would-be branch, we haven't found an ignore file (.ibgibignore).
This means that there won't be any files ignored and ALL files and folders will be included. Are you sure you want to continue? [(y)es, continue without an ignore file, (n)o, cancel and I'll add an ignore file.]
n
[confirmProceed_ifNoIbgibignoreFileInPath] complete.
[RCLIApp_V1_tfhruamt]>  echo: Ok, go ahead and create that ignore file and re-run the add command.

I typed in "n" here, because it's in parentheses. You can also just ctrl+c out of this.

So let's create that .ibgibignore. Here is a copy of mine that I'm using for my oldest, messiest monorepo, currently sitting at https://github.com/wraiford/ibgib

note: If you look closely, you may see that it is not strictly a monorepo, but rather is the outer shell which provides some organizing features as well as a shared tsconfig.base.json file. The "monorepo" conundrum is a byproduct of misunderstanding version control -- it is not inherent to version control but to current version control systems' approaches. Individual files, folders, groups of files and folders, derivative packages, apps, binaries, even devops clusters and more...these are all individual solutions to timeline compositional dynamics. The monorepo is a false choice which ibgib aims to obviate.

So create an .ibgibignore file in your my-project$> directory and use this as a template. Adjust to suit your needs. For me, this is like the root of my "monorepo" for ibgib. But I am planning on using the granularity to include other pieces. Some of these fall under devops, like package management (npm in ibgib's typescript form), but others may be for new things, like separate "packages" for documentation (readme, contributing, etc.), as well segregated testing packages (to reduce the npm package size if we are publishing to npm).

# start any line with ! to make it an include operation instead of exclude

# npm
node_modules

# other folders
dist
platforms
plugins
www
.git

# common extensions
regexp js ^.*\.(tmp|tgz|DS_Store|sw[mnpcod]|log)$
regexp js ^.*\.tmp\.*$
regexp js ^.*npm-debug\.log\.*$

# js/angular/ionic/etc
regexp js ^.*\.(idea|ionic|sass-cache|sourcemaps|versions|coverage)$

# typescript
regexp js ^.*\.(tsbuildinfo)$

# apps/libraries will be in their own branches
regexp js ^.*apps/(ibgib|plain-gib|nd-gib|ng-ionic-gib)/.*$
regexp js ^.*libs/(core|encrypt|ts|capacitor|helper|ga)-gib/.*$
regexp js ^.*archive/.*$

# forks are a funny thing, going forward may be slightly different with more
# granular capabilities. for now, i have a folder for forked repos.
regexp js ^.*forks/.*$

# private
regexp js ^.*\.(secret|private)(\..+)?$

⚠️ in some vim editors (maybe wsl2 only?), copy/pasting this comments out ALL lines. Make sure that the .ibgibignore is correct and every line doesn't start with a #.

Right now, these entries fall under three categories:

  1. comments - prefixed with # as may be expected
  2. literal names - matches if the last part of a path (node.js's basename) matches this exactly
  3. js regexp entries - javascript regular expressions that match against fully resolved paths

note: globs are not yet supported.

So for file/folder names, just enter the raw name if you want to exclude the item. I have the regexp entries for some folders so that the folder will exist but its children won't be ingested. Note that you can nest these .ibgibignore files within sub directories and it will only be in effect for that sub directory and any of its child directories. More proximal rules overrule more distal ones.

Also notice that I have .git here. This is because this project happens to have a large pack file (c. 150 MB) that makes my finer-with-age laptop run out of memory. So there is an arbitrary large-file limit in place at the moment. This is DEFINITELY not long term, and large files are absolutely what ibgib will shine with (because sharding -- again -- is about timeline dynamics and content addressing these chunks). This is not a problem with ibgib, rather it is an artifact of my lack of time in implementing a thorough sharding system. This is because the ibgib mechanism will provide a more general handling of this, instead of coding it here in this particular adapter in the node substrate level to handle the inability of web crypto api to hash streams. For smaller projects with smaller pack files, you may also be able to include the git folder for archival purposes.

note to self: the command i like atow (04/2024) for preserving the git log history in a file is git --no-pager log --decorate=full > gitlog.archive.txt (thanks SO here and here)

take 2: ibgib b2-branch . --add --name=my-project-main

So now, with the .ibgibignore in place, let's rerun the branch command:

ibgib b2-branch . --add --name=my-project-main

Expected output:

Created but did not activate a root B2tFS Branch IbGib, as well as any child B2tFS Item IbGibs for child files/folders.

ibgib b2-activate my-project-main

As this states, we didn't activate the branch. Right now, there's only one branch so operations will default to that single branch. But inevitably we'll have multiple branches, so let's go ahead and activate it explicitly.

ibgib b2-activate my-project-main

Expected output:

branch my-project-main activated. branchSpaceId: 5150786f69ef65e5c5d024cbc42f24f4a6281b2075fad67a26a5f521c1e82ba0

note: We could also have added the --b2-activate flag to the branch command when creating the branch.

And there we have it! We now have our first active branch created for our project!

Let's go through our basic workflow of adding and modifying files.

ibgib b2-diff

First, let's do our initial diff after adding the branch.

ibgib b2-diff

Expected output:

NO differences found.
branch my-project-main (branchSpaceId: 5150786f69ef65e5c5d024cbc42f24f4a6281b2075fad67a26a5f521c1e82ba0)
runningErroredDiffs: [none]
runningIgnoredDiffs: [none]

No surprises here.

Let's try adding a new file.

touch new_file_here.txt
ibgib b2-diff

Expected output:

YES, differences found but NOT applied.
branch my-project-main (branchSpaceId: 5150786f69ef65e5c5d024cbc42f24f4a6281b2075fad67a26a5f521c1e82ba0)
> my-project [START]
  | new_file_here.txt (new file)
  my-project [END]
runningErroredDiffs: [none]
runningIgnoredDiffs: [none]

ibgib b2-diff --apply

To simplify development, we are NOT going to use a filtered stage + commit process, i.e., selectively choose file/folders to stage and then commit. This additional step is extra code, extra complexity, and often creates errors when you commit part of the code and forget to include other code that should have been there in the first place (e.g. oops I forgot to include the file that defines the function consumed in one of the files I did commit).

That said, I'm not ruling them out forever. I do personally use selective commits for cleanness of the log. In ibgib, this is NOT a problem because improved logging dynamics is inherent in the design. So you don't need to do additional commands to "fix" a commit in order to "fix" the logging. "Logging", i.e., attaching written text/notes to versioned things, i.e. attaching metadata alongside data, is one of the many aspects where ibgib shines. This is because everything is an ibgib (content-addressable/deep linkable), including the metadata "logs". You can attach text to individual "punctiliar" ibgibs (single points in time) as well as to their corresponding timelines. Heck, you can add comments to the comments -- again, to a single comment, or to the comment's entire timeline (including editing, i.e. mutating any comment's text intrinsically). Indeed this is exactly the same code that will be used for issue tracking. Issue/bug tracking, discussions, code reviews/code comments, logging,...they're all the same thing: chat/metadata timelines associated with primary data timelines, which may produce derivative data timelines. So when you go to sync your code (push, pull, etc.) among spaces, you can sync the metadata (issue tracking, identity, etc.) at the same time, using the same graph transporting substrate, with the same cryptographic guarantees. This is just one glimpse into how to simplify architecture to enable the web3 metaverse people are scrambling to try to build.

So, now that we've reviewed our diff, hit up on the command line (or however to view the previous entry) and append the --apply flag.

ibgib b2-diff --apply

Enter the comment for the apply.

note: you can use the --text param to inline the message. It has synonyms 'txt', 'message', 'm', 'msg' atow (04/2024)

If this opens vim and you are unfamiliar, just hit i (to enter "insert" mode) and then type your message. When you are done, you hit esc, :wq, enter. This escapes into "normal" mode, the : brings up the command bar and wq + enter executes the write and quit commands.

Expected output:

YES, differences found, and YES they were applied.
branch my-project-main (branchSpaceId: 5150786f69ef65e5c5d024cbc42f24f4a6281b2075fad67a26a5f521c1e82ba0)
> my-project [START]
  | new_file_here.txt (new file)
  my-project [END]
Apply Diff Comment (in case we already forgot with our short attention spans):

added a test file

runningErroredDiffs: [none]
runningIgnoredDiffs: [none]

So the intended workflow is:

  1. make changes
    • add/remove/modify files & folders.
  2. exec the diff
    • ibgib b2-diff
    • inspect all the changes
      • remember wth you were doing
      • maybe write down into a temporary window (vscode) or buffer (emacs/vim-like) all of your notes.
  3. --apply changes when you're satisfied
    • ibgib b2-diff --apply
      • you can just hit up to see your shell's history and append the --apply flag
    • enter a message with all of those nice things you remembered
      • paste in any written notes.

space dynamics - push, pull, merge, sync, etc.

ibgib uses two broad categories of spaces atow (04/2024): local and outer.

Local spaces are meant to act as the active space when using an application. Outer spaces are actually client-based proxies to interface with other spaces which can be used for backups, synchronization, communication, websites, etc. Those outer spaces may be implemented via just the client + server, or they may actually be proxies to other local spaces. Though the only current implementation is an AWS cloud-based synchronization space, the future of DevOps can be thought of via space composition.

Since we are talking about proxies to other services, most of which are built upon secrets. The most common pattern is the use of API Id + Key, but no matter the specific implementation, it almost always is based on some form of secrets.

In ibgib, we encrypt these secrets as ibgib. In order to encrypt them, we must first have a secret and an encryption configuration/parameterization. As you may have already guessed, these are also stored as ibgib!

So to setup any outerspaces, we must first create a secret ibgib and an encryption ibgib. Once we have these we can create the outerspace, encrypting its private configuration (like api credentials) and only decrypting when needed at runtime.

ibgib secret --add

We will add a password secret. This will create an ibgib that represents your secret. We of course will not actually store your secret, nor even an entire salted hash of it (more on that in a moment). The secret ibgib, rather, will contain metadata about your password. So ⚠️ dont splash it around town, though according to good old Kerckhoffs, common sense and your security news feed, this metadata will inevitably be publicly known.

ibgib secret --add --name="example_secret" --secret-type=password --space-name="local_laptop_my_project" --hint="its pw duh" --description="this is an example secret. don't actually use this." --prompt

Type in pw twice for your password and confirmation.

⚠️ never actually use this as your password.

Expected output:

Secret added successfully (secret password example_secret^837A625DDD20E4F5844EA39D93ABF1CE7274D541B7F75E65D6643620014EACE8.E0E43548BDFD60164EBB52A3E182D856A226C3A63D66BE1CBE44F13FA28D68B4)
{
  "ib": "secret password example_secret",
  "gib": "837A625DDD20E4F5844EA39D93ABF1CE7274D541B7F75E65D6643620014EACE8.E0E43548BDFD60164EBB52A3E182D856A226C3A63D66BE1CBE44F13FA28D68B4",
  "data": {
    "n": 1,
    "timestamp": "Fri, 12 Apr 2024 14:40:22 GMT",
    "timestampMs": 72,
    "name": "example_secret",
    "type": "password",
    "expirationUTC": "Sat, 12 Apr 2025 14:40:22 GMT",
    "passwordProbablyCorrectInfo": {
      "substring": "c58e",
      "saltPrependedPerHash": "76839",
      "recursionCount": 168,
      "algorithm": "SHA-256"
    },
    "description": "this is an example secret. don't actually use this.",
    "hint": "its pw duh"
  },
  "rel8ns": {
    "ancestor": [
      "secret^gib"
    ],
    "dna": [
      "fork^87166A2C11395E7C6F90870C412360DBEEF237B467BCCEC1A4B4CF842F5BA598",
      "mut8^B7CCFF61AF1497C40A807B587385E73A4A033B5CC4F19F8E437D1F9CF43CD2C4"
    ],
    "past": [
      "secret password example_secret^E0E43548BDFD60164EBB52A3E182D856A226C3A63D66BE1CBE44F13FA28D68B4"
    ],
    "tjp": [
      "secret password example_secret^E0E43548BDFD60164EBB52A3E182D856A226C3A63D66BE1CBE44F13FA28D68B4"
    ]
  }
}

✏️ quick ibgib protocol data structure footnote (skip if you already understand the protocol): The ib string contains per-user-case metadata and this provides half of an ibgib's content address. The data contains intrinsic data/metadata at this single point in time. The rel8ns contain Merkle (cryptographic) links to extrinsic data (other ibgibs), similar to an object reference in OOP. The gib string contains hash-related metadata (derived from the ib, data, and rel8ns) and is the other half of the content address. If you look at rel8ns each ^-delimited address is in the form of ib^gib. This has many benefits over using just the hash as the address at the price of larger addresses. There many tricks to combat this though, so it is well worth it and provides a HUGE advantage over most existing DLT protocols.

Now there is quite a bit to look at here, even discounting the ibgib protocol bits that you are probably not familiar with. Some are straight-forward, like the name, hint and description. But note that these exist for your organizational and mental retrieval purposes. A password manager is great until you get your password manager hacked. With this metadata, instead you have the ability to provide yourself with mental context. You can provide information and/or disinformation here, or just trigger words to help you mentally retrieve the password.

Also I can all but guarantee that you haven't seen the passwordProbablyCorrectInfo field. This is an interesting consequence of a non-server-centric execution environment.

In a "trusted" server execution environment (though remember any server can be compromised), usually the entire password is transformed, often in the form of a single iteration of a hash(password + salt), i.e., a salted hash (though be careful of length extension attacks , always append the salt). But in a distributed environment, we do not want to store the entire password projection. If we did so, then in order to brute force the password, we would only have to check against this hash (which we must assume an attacker will gain a la Kerckhoffs). But it is extremely convenient to have some method to let the user know when they have entered the wrong password. That's where passwordProbablyCorrectInfo comes in. What this does is gives a partial substring of the hash projection function, dynamically parameterized with saltPrependedPerHash, recursionCount and algorithm. We can then check the user's entered password against this. At 4 letters, the substring is relatively unlikely to collide with a user's mistyped/wrong password unique variants at a rate that ranges from 1 in 100 to 1 in 2000. The longer the substring, the more unlikely, and an attacker only gains knowledge (at the same rate) of possible candidates for brute forcing passwords. Without this, they would have to decrypt all of the data to check that a password is correct, which would be more expensive with more data.

In short, the longer the substring, the more confident we are of the password. But then again, the more information a would-be attacker gains when brute forcing. Right now, it's impossible for me to make this decision so it's parameterized and this will play out per use case with requirements. And in code, if the entire hash is desired, this is simply one concrete parameter set (so it would take no code change).

So when a user is prompted for a secret, the secret's name, hint and description (all public fields) should be shown to give the user context. After the user enters the secret, it is transformed using the passwordProbablyCorrectInfo configuration to produce a hash. If that hash includes the passwordProbablyCorrectInfo.substring, then it is probably correct and the private info decryption proceeds.

You can see this information using the --info flag on the secret command: ibgib secret --info.

ibgib encryption --add

Now that we have a secret, we can add an encryption configuration that we will combine with the secret to encrypt our sync space's API credentials.

ibgib encryption --add --name='example_encryption' --encryption-method=encrypt-gib --space-name='local_laptop_my_project' --description='simple encryption parameterization. remember this is an unproven algorithm created outside of mainstream security. so dont use this for anything important right now.' --hash-algorithm='SHA-256' --initial-recursions=50000 --recursions-per-hash=2 --salt='specify only if needed. will use a random hash by default' --salt-strategy='prependPerHash' --block-mode=true --block-size=10000000 --num-of-passes=3

Expected output:

Encryption added successfully (encryption encrypt-gib example_encryption^7F81C40A60BD6C48C5894BDFDCBA80A8AE973886E6635AB1B4D905C867D0D5B2.D8B916927A1C4B8D4DAD2B06B20AD053E25E1BA82AEF8E387759848826EC193C)
{
  "ib": "...",
  "gib": "...",
  "data": {
    "..."
    "method": "encrypt-gib",
    "name": "example_encryption",
    "description": "simple encryption parameterization. remember this is an unproven algorithm created outside of mainstream security. so dont use this for anything important right now.",
    "hashAlgorithm": "SHA-256",
    "initialRecursions": 50000,
    "recursionsPerHash": 2,
    "salt": "specify only if needed. will use a random hash by default",
    "saltStrategy": "prependPerHash",
    "encryptedDataDelimiter": ",",
    "indexingMode": "lastIndexOf",
    "blockMode": true,
    "blockModeOptions": {
      "maxBlockSize": 10000000,
      "numOfPasses": 3
    }
  },
  "rel8ns": { "..." }
}

note: I've condensed it a bit since we have already had our quick lesson on the ibgib data structure

The data field mainly contains the settings for the encryption method that we use. In this case, we are using encrypt-gib because it's the only one I've implemented atow (04/2024) in this RCLI and because it is extremely interesting to me right now, because it has a novel approach to encryption (and I invented it). It builds an encryption scheme entirely around the same parameterized hashing function, from the key stretching phase to the iterative encryption rounds - which uses a novel jit 1-time alphabet generation algorithm instead of an XOR-based combiner function to generate the keystream. You can find more details about encrypt-gib at https://www.npmjs.com/package/@ibgib/encrypt-gib .

⚠️ ENCRYPT-GIB IS AN UNPROVEN ENCRYPTION ALGORITHM. CONSEQUENTLY ALL CURRENT API CREDENTIALS ENCRYPTED WITH THIS ALGORITHM MAY BE WEAKLY PROTECTED. USE AT YOUR OWN RISK. ⚠️

When we implement other encryption algorithms like AES, the specific parameterization of it will be stored here in this encryption ibgib.

Now that we have both a secret ibgib and encryption ibgib, we can create our outer space that we will use to sync with the cloud.

sync prerequisites

Right now this prototype has a single outer space implementation: a sync space which uses AWS cloud -- DynamoDB for ibgibs under 180 kB and S3 for larger ones. All binaries ibgibs use S3. So before we can add the space we must initialize this AWS infrastructure.

DynamoDB

create a table...

  • partition key must be named 'ibGibAddrHash'
  • no sort key
  • 1 global index named 'tjp-n-index'
    • partition key 'tjp' (String)
    • sort key n (Number)
    • projected attributes 'All'
S3

Create a bucket...

  • disable acls
  • disable versioning
  • no public access
iam

you can decide how to organize groups vs. roles vs. users. but your aws-cli client has to ultimately have a policy and specific CORS settings, and then the user should be a cli user with the corresponding credentials.

policy json:

{
 "Version": "2012-10-17",
 "Statement": [
     {
         "Sid": "VisualEditor0",
         "Effect": "Allow",
         "Action": [
             "dynamodb:BatchGetItem",
             "s3:PutObject",
             "s3:GetObject",
             "dynamodb:BatchWriteItem",
             "dynamodb:ConditionCheckItem",
             "dynamodb:PutItem",
             "dynamodb:DeleteItem",
             "dynamodb:GetItem",
             "dynamodb:Query",
             "dynamodb:UpdateItem"
         ],
         "Resource": [
             "arn:aws:dynamodb:us-east-1:124312431243:table/x-gib-dynamo-table-name",
             "arn:aws:dynamodb:us-east-1:124312431243:table/x-gib-dynamo-table-name/index/tjp-n-index",
             "arn:aws:s3:::x-gib-bucket-name/*"
         ]
     }
  ]
}

CORS for S3 bucket:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ]
    }
]
ibgib sync --add

Now that we have those resources created, we can create the outerspace. We should be able to provide the following settings. You can search the terms in the codebase to find their jsdocs (many in aws-dynamo-space-v1.mts).

touch sync_space_settings.private

Edit the file with your particulars:

{
    "syncSpaceSubtype": "aws-dynamodb",
    "dataOverrides": {
        "dontStoreStatusUpdatesInSyncSpace": true
    },
    "detailsOverrides": {
        "primaryKeyName": "ibGibAddrHash",
        "accessKeyId": "ABCABCDEFABCDEF123AB",
        "bucketName": "s3-bucket-name-here",
        "region": "us-east-1",
        "secretAccessKey": "abCabCabCabC123AbcAbcAbc456aBcaBcaBc7890",
        "tableName": "dynamodb-table-name-here",
        "maxRetryThroughputCount": 5,
        "maxRetryUnprocessedItemsCount": 5,
        "putBatchSize": 22,
        "getBatchSize": 100,
        "queryBatchSize": 5,
        "throttleMsBetweenPuts": 100,
        "throttleMsBetweenGets": 100,
        "throttleMsDueToThroughputError": 3000
    }
}

I'm not going to go into all of the parameters here, but a quick note that dontStoreStatusUpdatesInSyncSpace set to true will keep the progress of sync sagas from being stored in AWS and may cut down significantly on the amount of traffic over the wire/stored in AWS. But on the OTOH you won't have an audit log in the cloud, it will only be in your local source space.

With that settings file created, we can now add the AWS-based outerspace.

ibgib sync --add --name='example_syncspace' --desc='simple aws dynamodb and s3 sync space' --aws-dynamodb --space-name='local_laptop_my_project' --input-path='sync_space_settings.private' --encryption-name=example_encryption --secret-name=example_secret

Note here that --name specifies the name for the space we will create, and --space-name is the name of the local space in which we will store the reference to the sync space.

ibgib b2-sync --to=example_syncspace

Now that we have a sync space, let's put our files and folders. To execute our initial sync, we will specify our my-project-main branch.

ibgib b2-sync --name=my-project-main --to=example_syncspace

OR

ibgib b2-sync my-project-main --to=example_syncspace

OR

ibgib b2-sync --to=example_syncspace

⚠️ If we leave out the my-project-main as in this last case, it will prompt us if we want to use our active branch, which in this case would be correct. But we don't always want to do this!

Expected output:

sync_log 7aa4741e1dc18c7e70716d60: 0.349ms start
sync_log 7aa4741e1dc18c7e70716d60: 7.434ms awaiting all startSyncPromises starting...
sync_log 7aa4741e1dc18c7e70716d60: 10.17ms
sync_log 7aa4741e1dc18c7e70716d60: 10.669ms getLocalUserSpace starting...
sync_log 7aa4741e1dc18c7e70716d60: 36.728ms getLocalUserSpace complete.
sync_log 7aa4741e1dc18c7e70716d60: 39.193ms syncSpace witness starting...
[AWSDynamoSpace_V1][routeAndDoCommand][put]
sync_log 7aa4741e1dc18c7e70716d60: 151.252ms syncSpace witness complete.
sync_log 7aa4741e1dc18c7e70716d60: 151.88ms awaiting all startSyncPromises complete.
started
inserted
inserted
[AWSDynamoSpace_V1][sendCmd] AWS throughput error (ProvisionedThroughputExceededException). will retry 1 of 6 in 6000 ms...
...
inserted
sync_log 7aa4741e1dc18c7e70716d60: 6:19.884 (m:ss.mmm) StatusCode.complete
completed
sync_log 7aa4741e1dc18c7e70716d60: 6:19.914 (m:ss.mmm)
[handleB2tFS_sync_exec]: 6:20.190 (m:ss.mmm)
[RCLIApp_V1_mtehfrqd]>  echo: saga 7aa4741e1dc18c7e70716d60 completed successfully. Processed 130 ibGibs.

Here is the To reference this root ibgib, you can use:

b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375
[handleB2tfs_sync]: 6:32.961 (m:ss.mmm)

The time will vary here, depending on the size of your graph, your internet connection, and your read/write capacities on DynamoDB (i.e., how many times read/writes fail due to throttling). In my case, I have a relatively low amount provisioned with a higher throughput for auto-scaling.

🔬 Remember, this is a prototype. In particular, this is an extremely slow fat-client sync space using DynamoDB + S3 only because I had prior experience already with these. A graph back end for a fat client, or even better a thin client to a native ibgib server/endpoint via web sockets or similar would be ideal, to really leverage the savings from the graph structure. There are too many additional benefits to list here in this ellipsis.

Note that in our output we got:

b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^AA151EC1E91DAE2F2B8C1CB150A6BE11182235CBA64889E5DC49853B8183D112

Remember we did not sync the branch ibgib itself, rather, we have synchronized the root item of that branch. In this case, we can glean the following information from this ib^gib address (without having to look at the full ibgib record):

  • it's a B2tFS item
  • its type is "folder"
  • the "saferized" name is "my-project"
    • reduced character set and length
    • the raw name requires the full record
  • the "saferize" algorithm is "v1"
  • the raw name hash is "1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904"

💫 An extremely knowledgeable ibgib protocol understanding will also tell us this is the "Temporal Junction Point" (TJP) of this ibgib. This stems from gib (hash) part of the ib^gib addr having only one hash. The TJP is like the birth of a timeline. It's the first address in a timeline, and this is how you can reference an entire timeline. Each subsequent ibgib frame in this timeline will have a gib like 2BB83730561A3FD4A07472D74822C52DF35CDC48FB6958A947CFEC757BAA8F9E.AA151EC1E91DAE2F2B8C1CB150A6BE11182235CBA64889E5DC49853B8183D112, which contains this TJP gib hash, in addition to the punctiliar hash which you will find in other DLT content-addressing schemas. This is hugely important and an integral part of time being a first-class citizen in the protocol.

So in summary, we have put a folder timeline whose dependency graph comprises all child binaries (in a file/folder hierarchy), as well as other dependency metadata ibgibs. So a bit like git's commit hash, this ib^gib address now represents the entire history of all data/metadata that existed to get to this point in time.

deep dive into the b2tfs_item ibgib we synced

Let us look real quick at the full ibgib record corresponding to this address.

NOTE: In the following command, you will have to put in your own address that you received in your output.

ibgib info --addr="b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375" --space-name=b2s_my-project-main

Expected output:

{
  "ib": "b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904",
  "gib": "1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375",
  "data": {
    "n": 0,
    "timestamp": "Wed, 01 May 2024 11:10:13 GMT",
    "timestampMs": 832,
    "uuid": "68a9016e894173d765e9a6bd017c3d4beff482af9b8ba3a09add710abf6c666b",
    "isTjp": true
  },
  "rel8ns": {
    "ancestor": [
      "b2tfs_item^gib"
    ],
    "dna": [
      "fork^94E2B37DC7E225089E47700392253CF0E5A3379AD98949DE93F04BAAE257F6BD"
    ]
  }
}

This is a relatively sparse record. This is because it's the TJP (See previous note for more info on TJP). It only has a single dna in its rel8ns: a fork of its primitive ancestor b2tfs_item^gib. This record contains the ibgib's uuid id field, which is useful when we do not want to reference an ibgib via its full addr or gib, though remember this requires a full load of the ibgib to get since we do not include it in our ib field in this use case.

Let's look at the "same" ibgib but later in its timeline using the --latest flag:

ibgib info --addr="b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375" --space-name=b2s_my-project-main --latest

Expected output:

addr: b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375
latest Addr: b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^E98F3F2034AC585EDA492F439D978496F119076A8A17E212942675D3365026AE.1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375
{
  "ib": "b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904",
  "gib": "E98F3F2034AC585EDA492F439D978496F119076A8A17E212942675D3365026AE.1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375",
  "data": {
    "n": 3,
    "timestamp": "Wed, 01 May 2024 11:10:15 GMT",
    "timestampMs": 692,
    "uuid": "b9b22f2c9a6686cbbd689eb1d77ce41d3634ee2ed8256d6a283607618d86677c",
    "fsType": "folder",
    "name": "my-project",
    "saferNameVersion": "v1",
    "nameHash": "1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904",
    "diffTransactionId": "2ba3cac7fa53ac55f8bf40297055ed6a04403043de4d06bad823d06e3d8288d4",
    "filterPatterns": [
      ".ibgib",
      "node_modules",
      "node_modules",
      "dist",
      "platforms",
      "plugins",
      "www",
      ".git",
      "regexp js ^.*\\.(tmp|tgz|DS_Store|sw[mnpcod]|log)$",
      "regexp js ^.*\\.tmp\\.*$",
      "regexp js ^.*npm-debug\\.log\\.*$",
      "regexp js ^.*\\.(idea|ionic|sass-cache|sourcemaps|versions|coverage)$",
      "regexp js ^.*\\.(tsbuildinfo)$",
      "regexp js ^.*apps/(ibgib|plain-gib|nd-gib|ng-ionic-gib)/.*$",
      "regexp js ^.*libs/(core|encrypt|ts|capacitor|helper|ga)-gib/.*$",
      "regexp js ^.*archive/.*$",
      "regexp js ^.*forks/.*$",
      "regexp js ^.*\\.(secret|private)(\\..+)?$"
    ]
  },
  "rel8ns": {
    "ancestor": [
      "b2tfs_item^gib"
    ],
    "dna": [
      "fork^94E2B37DC7E225089E47700392253CF0E5A3379AD98949DE93F04BAAE257F6BD",
      "mut8^ADD3C88ACA618F3F4B17EADB6EAFC6E7F0B0FBF55AF59C148157E7A593B8C6AA",
      "rel8^5E98253FF960A86B37393447B0AE89D46DBE0A9CF1A0C125E5AD97538683753A",
      "rel8^7881439BA27A2078DA5F6A989BFECF49A0D40B149E3E89D97481DA3D445926BC"
    ],
    "past": [
      "b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375",
      "b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^1DF633468810169967197B9AFD1E69350282E4952928A8D4CFAC902D1D681C26.1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375",
      "b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^BF4287DD5AF62D044E0A07E8C675B9AB3D41C4223565FC17166298865C0A184E.1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375"
    ],
    "tjp": [
      "b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375"
    ],
    "b2tfs_child": [
      "b2tfs_item file .gitignore v1 bc37d034bad564583790a46f19d807abfe519c5671395fd494d8cce506c42947^5A52AF47A76D80DBC06754FEEEAC1AC26377B5CA279B49461CDD3DA5098A2CC0.7EF3DFD2F9D3640BBF76FDBDEC12AAFF4D5668BC619D5DF014912F5663618331",
      "b2tfs_item file .ibgibignore v1 2b67e20b72b67518d52f44b5b84353f2e106e0c1383d1653e2492cee4cdeeeda^DD3D406663CA3F1F0B3274EA7B7AC11049926B3BFDC2BD0BC27BA1A106C400DC.F7BB2E0BF855D84E6DA214E327F50782CB35EFD1608D2B7F9A0B1F73D02EF360",
      "b2tfs_item folder .vscode v1 27bf025903b14c7d22e5415f78b31443828f0a7ecff34a2d7e722624550282d6^84F4F569CE79CE4BA90F81C35762589B3712A8BB5DF8835D12E211BA5851CEE1.BE60F3DBE5B1505788EABD5D8C5D0E70E74FA6E7A7E1F0455A70D2C5EF7B03C8",
      "b2tfs_item file README.md v1 b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5^9933C8DBD62AED2FCA4EF1BC7658585D7692BA295DD80FA46852EC92DB52BD9C.B76D251A614B20658BB3DDD33AE7173B4B3BAE55A1A87C1DDCDB5BAC5B21E46C",
      "b2tfs_item folder apps v1 d56f6359d240f69e4164425b599d08869574fc013b9e5727951048914db12c5b^ADD88AB89C94E895C4B4E5D90F4F9F20539493EBE9D4CEAE90CFD33CD82777B2.BCF1F49AFDF4224498410D5C6505EA73F20AD99071FA98385D5BBEB17F36B67E",
      "b2tfs_item folder archive v1 0eb3e36bfb24dcd9bb1d1bece1531216b59539a8fde17ee80224af0653c92aa3^3F9F1F32F5249DDECB858E022C309676DDBBF117DB9EEB0F7BCDD0009284D649.7C39F736EC1561F8D369CCF3CA5F579C472DC7AF70DFCC8B5A31BFABF08493DB",
      "b2tfs_item folder forks v1 47dc89965a85e2c5e64a6a221c1a04f7445f5fae9d4238b286e8cd039c8d19b6^409B6CF7727FF5FBB8F4EA590D28D6B67510EEF496F438AA421C8095686426B1.00391EEDA801D4EB2C9AF1E3157BA91DAE06D83AB3E95659CF4F6A0F37865D8C",
      "b2tfs_item folder libs v1 739a304e183a900711f6497e6544a814ef5367da89ccedad067fc1a3f0814b41^AE33C6017F8147553A42634489383FA9A48F1309D4FA90B41023FFFD6E4F918D.FF463351B05F754A23023E728F2E09470826524DFCAE7E2C4FFF53A0378391CE",
      "b2tfs_item file new_file_here.tx v1 f2f77bbba7cd38c7b7444904e4c7c3c86e601e016722acece4c4c1d44a1541ef^607BB1319B0A1FA90109B5A19B5523013AA3ED71F9FC77E9C16C301237B8698F.BB95E25D22F40F9D6A35F5CB1D219FC111FCC88D56E51FCE7A5CCDDEF60A9C81",
      "b2tfs_item file tsconfig.base.js v1 0b280a445be167f54cd916c0718c952b8e0d4ca9621903d05eec25efd4c6ed6d^86E48D1BFD90F0D3D676467F38E8648DD6DE99A33BA61BD486C494B28853E0CA.349EA880474F955AD2512B17CAB706032C04E4326C9C66AA32345C8613EA2808"
    ],
    "comment": [
      "comment initialcomment^FC35868DFCAD68591D3EBA2132DD6024FC5348E44EF3C30B5DDAB62FDB493906.B207B1EE3D27991AF8D8CD8080CC18D35506A1B3558D2045FF95753D2CBCCEBC"
    ],
    "target": [
      "b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^BF4287DD5AF62D044E0A07E8C675B9AB3D41C4223565FC17166298865C0A184E.1943BC4CBE166AFE7511E5D1024A788E43A9CDA0B445BFF284F739553A0A1375"
    ]
  }
}

Ah, that's more like it. This contains intrinsic data to the folder, including e.g. the filter patterns that were used in its generation, as well as the diffTransactionId (a B2tFS-specific field, not ibgib protocol).

This entire graph is now encompassed

ibgib b2-sync --to=example_syncspace
ibgib b2-branch . --add --name=my-project-main --sync-space-name=example_syncspace...

At this point, we have some AWS resources that contain the ibgibs for our VCS. These ibgibs include the files themselves (binaries) stored in S3, along with the version control (and other) metadata mostly in DynamoDB.

Now let's say we want to pull that down to another location. Let's do that now.

In many other VCS's this is cloning, but I hesitate to use that term yet because we will be composing timelines differently than existing paradigms, and I am unsure of what the "final" product will look like. Currently in my mind, "clone" may be a misnomer.

ibgib b2-branch . --add --name=my-project-main --sync-space-name=example_syncspace --from-addr="b2tfs_item folder my-project v1 1c7cd944c28cd888904f3efc2345198507c47563c4b51a7acc51e3df4e681904^AA151EC1E91DAE2F2B8C1CB150A6BE11182235CBA64889E5DC49853B8183D112"

developing

...moving to ibgib-based workflow

build/dev/contribute tips

when you want to test some behavior manually

sometimes it's nice to open up a repl at some state with some assumptions. the respec's do this well and by default (atow 01/2024) do not delete the output test folders under b2tmp.

so you can execute an npm test run and navigate to these folders and within one of those do your manual testing. i often will use a node ../../.. repl or whatever.

note: you may want to set the desired test only to run by changing its unit test feature. change its respecfully block to respecfullyDear and turn on the veryPolite flag.

ibgib review - skip this if you're already familiar with ibgib's architecture

A quick reference on the IbGib v1 interface exposed in ts-gib :

export interface IbGib {
  /** per use-case metadata */
  ib: string;
  /** cryptographic hash info of other three props. often there are two hashes: 1) a punctiliar hash for an individual record. 2) a temporal junction point hash for the very first address in that ibgib timeline. */
  gib?: string;
  /** intrinisic data */
  data?: any;
  /** named links/edges to other ibgib nodes for decoupled extrinsic data */
  rel8ns?: { [key: string]: IbGibAddr[] };
}

note: this is simplified and condensed pseudocode from multiple interfaces with generics and other complexities.

Each address is composed of the ib and gib properties concatenated using a delimiter (^ by default).

quick background on ibgib a la code as data

Ibgib is largely about meta-programming. The raw ibgib data protocol shape enables cryptographic content-addressing, building cryptographic DAGs with the ability to both:

  1. (re)hydrate via dna transforms as in event sourcing requests/events
  2. apply dna in different contexts, similar to applying diffs in git's version control in different branches when performing merges.

So both of these essentially boil down to code as data meta-programming.

Witness interface: add behavior to ibgibs

Witnesses in ibgib are those that have this same data protocol semi-structure shape (IbGib interface), and a single behavior/function exposed: witness.

export interface Witness<
    TIbGibIn extends IbGib,
    TIbGibOut extends IbGib,
>
    extends IbGib {
    witness(arg: TIbGibIn): Promise<TIbGibOut | undefined>;
}

note: this is simplified and condensed pseudocode from multiple interfaces with generics and other complexities.

So a Witness is like a universally content-addressed function. The witness itself has an ib^gib address, intrinsic data and extrinsic rel8ns, and it has a single function that takes a single incoming ibgib argument and returns a single ibgib result.

brainstorming development options for rcli (archive section)

These were written when trying to first develop this app.

AFAICT there are a couple options for implementing this RCLI:

  • incoming text gets parsed like a normal rli request and starts motions of some low-ish level of ibgib graph + space.
    • this parsing and routing is done just via functions, without any kind of ibgib conversion, both the incoming args, the produced output, as well as no witness handling those incoming args.
  • I build out a new witness class structure that descends directly Witness
    • does NOT descend from: space, robbot, or app
    • incoming "request" (it is an "R"LI after all) is assumed to be a text, i.e. CommentIbGib_V1.
  • I descend from app witness AppBase_V1
    • does have routeAndDoArg, doComment already going.
    • the rli sounds like an app to me
  • I descend from robbot witness RobbotBase_V1
    • does have routeAndDoArg already going
    • plumbing in place for listening to a timeline stream context for incoming comments.
      • for now, we don't need pic interpretation though that's definitely in the pipeline.
    • already has lex setup for parsing incoming requests
    • CONS
      • rli doesn't sound like a robbot, but rather an environment for a robbot.
      • this may be down to our paradigm shift from apps to assistants (robbots) as layers of indirection to apps. So instead of thinking of a robbot as "part of" an "app", with ibgib we're streamlining interfaces to shared data universes (metaverse projections).
        • as a side note, a "metaverse" is more likely a projection of the "universe".

Ultimately, I think the path forward is an amalgam of these approaches. I would prefer to keep it simple, but the raw parsing of the incoming requests doesn't work with my ideas for local spaces (similar/isomorphic to "nodes" in other paradigms). And I would prefer even to use either an app or a robbot. But I'm leaning towards both an app that gets bootstrapped and a robbot that the app creates by default and routes requestline comments to.

UPDATE: I have moved toward the amalgam of a RCLI app + RLI Robbot (Rolly). The RCLI app acts similar to a standard CLI in spirit. BUT it leverages ibgib's architecture and uses a chat-style context ibgib for the interactive REPL and converts "command lines" to comments in this chat context. Rolly can then also interpret other chat requests that could resolve to command lines that the RCLI interprets. But this doesn't have to be the case. You could chat with Rolly similar to interacting with a man or --help, but more in a chatbot-style. ALSO you can add "comments" in your RCLI interaction to document intent. Basically you are capturing context and enabling features as a matter of course, much like other implementations of ibgib beyond existing paradigms.

bootstrapping - spaces, apps & robbots

A space...

  • is a colocation of ibgib.
    • Essentially is the equivalent to a mathematical set or group.
  • that colocates spaces is a metaspace.
    • starts off with zero memory as a zero-space.
    • over time, ultimately given monotonically increasing metaspaces, each one becomes "the same as" or "effectively indistinguishable from" the other except in their pasts? (all roads lead to rome)

An app...

  • is one layer "on top of"/"orthogonal to" a space.
  • provides the execution mechanism that changes/mutates ibgibs within spaces.
  • is equivalent to the physics of spaces.
  • can itself "move" from space to space,
    • which is to say, when you change which space(s) the app is acting against, it has moved.
  • as a witness is not a subtype of a space, but a separate branch.
  • commonly witnesses only a single ibgib arg upon startup, with some occasional update witness args when changing settings, preferences, etc.
  • that acts upon other app ibgibs is a metaapp.

A robbot...

  • is a witness with agency that acts within an app+space(s) context.
    • it has agency in that it acts within an app as an execution context (scheduler), as the app is determining the "physics".
  • can "move" from app+space(s) context to app+space(s) context.
  • commonly witnesses many ibgib args relative to the frequency that an app witnesses ibgibs.
    • this frequency can be similar in scope to the frequency that a human witnesses ibgibs.

differentiating apps and robbots...

  • is tough.
    • is an app the "flesh" of a robbot?
    • can an app exist outside of a robbot?
    • am i confusing a robbot with a witness?
      • especially in light of ai and specifically ChatGPT (chatbot ai) in news atow.

bootstrapping

So in order for anything to happen, first you have to start with a space. And ultimately the first space is a metaspace. But we don't have any previous spaces to look at to get parameters, so the first metaspace has to be a zerospace.

ionic/capacitor mvp bootstrap

first run...

  • angular app component is constructed
  • all powerful ibgibs service is initialized
  • local space initialized
    • zerospace is created (IonicSpace_V1 with default values)
    • bootstrap is looked for (but NOT found) using that zerospace
    • local space is created
      • prompts user for a name for the local space
    • bootstrap is created
      • uses zerospace
      • points to local space
  • special ibgibs are initialized/created
  • all powerful ibgibs service initialized fires
    • app is ready to go

successive runs

  • angular app component is constructed
  • all powerful ibgibs service starts
  • local space initialized
    • zerospace is created (IonicSpace_V1 with default values)
    • bootstrap is looked for (and YES found) using that zerospace
      • and validated
    • local space addr is gotten from bootstrap
      • not cached and regotten most times space is needed
  • all powerful ibgibs service initialized fires
    • app is ready to go
bootstrap in this rli
  • user types in cmd in the form of ibgib [...args]
    • args list
      • --b2tfs-root-dir
        • short: -fsrd
        • path to root of ibgib spaces
        • also is the default unnamed argument (doesn't start with - or --)
        • default to ./.ibgib
      • --zerospace-dir
        • short: -zsd
        • synonym: --filesystemzerospace
        • path to zerospace directory
        • defaults to __zerospace__
        • relative or absolute [^1]
      • --memzerospace
        • short: -mzs
        • synonym: --in-memory-zerospace
        • boolean flag indicates if we're using an in-memory only zerospace (transient metaspace)
      • -b / --bootstrap-file
        • path to the bootstrap^gib file
        • defaults to bootstrap^gib.json
        • relative or absolute [^1]
      • --interactive
        • flag to indicate if repl-like experience with robbot
        • to be implemented once we get a robbot (chatbot) going
      • --addl-metadata
        • optional additional metadata to be attached to the ib
  • zerospace created
    • if -fzs/--fszerospace/--filesystemzerospace, look in that folder
    • if -mzs/--memzerospace, use in-memory zerospace.
    • no arg defaults to -fzs="ibgib"
    • zerospace is created in subfolder __zerospace__
      • note: in mvp, this is 000_default_space I think

[^1] relative to fs-root-dir (e.g. [fs-root-dir]/somepathorfile) OR absolute path e.g. /Volumes/my/path/somepathorfile

simplest request: ibgib

Simply executing this rli main function without arguments should bootstrap a local space, app & robbot.

note: If at some point we want a wizard bootstrapper, then that will be a robbot specifically for intepreting requests and overall chatting with the user to create what is desired.

generalized local space (node/app?) bootstrap

b2tfs-gib (fs+vcs)

:under_construction: b2tfs-gib is not yet implemented. so right now, these are notes on getting this going.

Also note: i use the term directory and folder mostly interchangeably.

Filesystems are a subset of ibgib's data architecture. Each fs directory has intrinsic data (that we call metadata), but its primary purpose is to contain children. This is equivalent to a rel8n with a rel8nName like 'child'. Each file in an fs has two types of intrinsic data: the file's contents and the file's metadata (used by os often). But there are no "rel8ns", i.e. no children, because this is the role of a directory. Each folder/file has an address that can be considered part of each's metadata, which is called the path.

So, ibgib is a more powerful superset, enabling all of these qualities. The path is a constrained ib with no inherent gib hashing metadata. This ib is a slash-delimited (backslash in Windows). All intrinsic data can be represented in the internal data property, and all directories' contents can be represented by a named 'child' rel8n in the rel8ns field.

...something about vcs -> time that is inherent in ibgib with past and ancestor rel8nNames.

When we combine the version control system aspect to the fs, we effectively are introducing TIME as a first-class citizen in what we previously

TIMELINE BASED -- NOT FILE/FOLDER

This entire process is to make it easy for users of previous technologies, e.g. src code like git or document editors like textpad/notepad/docx/docs or image/video editors like illustrator/whatever else. This means we are working at a TIMELINE level, no other. With that in mind, and restricting ourselves to src code version control transcendence:

  • I want a mapping of files/folders to keep track of timelines.

    • (folders/directories used interchangeably here)
  • There is a single timeline that is the composite of these other timelines.

    • this is assumed to be a folder/directory in git/fs.
  • In git, this is solved at the repo level.

    • The repo acts as the "root" directory of all other files/folders (trees) children.
    • These are the only types of timelines and each diff is an action upon one of these items.
  • a commit is a collection of these diffs

    • though git doesn't store deltas
  • so an "add-root" is like an "add-repo"

    • "add-repo" could be a synonym
    • the "root" must map to a hierarchical ibgib "folder"
    • we don't really care where these files are though on disk
      • but people nowadays think in these hierarchical paradigm
    • we want to reserve the ability to dynamically compose these repo "folders" from various ibgibs that can live wherever the hell they want to live
      • ibgibs can "work remotely"
    • even though we are working within a single "root" "repo", we want "files" (and simlink-like "folders") to be able to belong to multiple other "repos".
      • i.e. if a timeline gets updated in one repo, we want the ability to update that timeline if it exists in the ibgib space (not just in the repo).
      • but we should also be able to specify if we only want intra-repo changes?
        • "heterogenous mini-merges"
      • this means we must have a wrapper for the file/folder and the concept of the inner ibgib payload(s).
    • we want the ability to dynamically compose individual files from multiple ibgibs.
      • e.g. we have a function ibgib that we want to webpack/rollup/whatever into a single src code text file.
      • e.g. we have multiple chapter ibgibs that we want to compose into a "book" src code text file.
      • e.g. we have multiple visual objects/transforms/filters/layers that we want to compose into a single "image" file.
  • should be able to have multiple spaces share (sync) roots. *

  • root has a rootName and a rootPath, and of course the root's tjp addr.

    • rootName maps to the root's dirName or --name override when root is initialized.
    • rootPath maps from the ibgib's space to the root's outputPath
      • rootPath is always different per space.
      • the rcli binary has a cwd for the space (often ./.ibgib)
      • don't want to have to deal with saving mappings of space->rootPath all over.
        • can't save the mapping on the root ibgib itself as we want to be able to share this root ibgib among multiple spaces.
        • can't save this on the RCLIApp for the same reason that the app should be portable among spaces.
        • don't want to save this on the space itself because it's busy enough as it is.
      • @examples
        • ibgib space is "inside" the repo
          • ~/my-repo/.ibgib
          • rootName of my-repo
          • rootPath for of ..`
      • so if ibgib space is at ~/my-repo/.ibgib and the
  • paths act from [rootName]/fake/ibgib/path/[filename/dir-name]

  • paths act from [rootName]/fake/ibgib/path/[filename/dir-name]

b2tfs rcli commands

these commands can be executed as one-offs or in the interactive repl (--interactive flag).

note: This documentation is generated as I'm creating these, so atow (01/2024) they are doubling as dev notes. Needless to say, these might be (and probably will be) out of date. With each command, I am including where to look at in code for the real deal. In addition to the actual code, you should find also a lot of comments/docs for individual functions/modules (But any documentation can always be out of date)

  • many commands have synonyms, some longer and more descriptive, others more terse.
    • i am not of the religion that there should be one and only one command syntax.
  • all commands have an implied/optional --data-path param that specifies what our working metaspace datapath is.
    • similar to the existing --interactivecommand, this defaults to ".ibgib".
    • also similar to the --generate-source-file command, the actual "cwd" for relative paths will be one level up from this metaspace --data-path.
      • this stems from placing the metaspace path inside the root cwd folder, similar to how existing tools like git place the .[tool] folder inside their root cwd folders.

--b2tfs-init

> ibgib --b2tfs-init [--data-path=.ibgib]
  • initializes the b2tfs index in a space.
  • remember, this is different from --init command (no b2tfs)
    • --init must occur first (it's what sets up the overall ibgib local space)
  • atow (01/2024) this does not create a root branch
    • so the next command should probably be a

b2tfs-info

b2tfs-add-root-branch

> ibgib --b2tfs-add-root-branch [path to folder] [--data-path=.ibgib]
> ibgib --b2tfs-add-root-branch --input-path=[path to folder] [--data-path=.ibgib]
  • bare arg: --input-path
examples
my-repo> ibgib --b2tfs-add-root-branch .
my-repo> ibgib --b2tfs-add-root-branch ./my-project
dev notes (previous thoughts when doing this cmd)

--b2tfs-add-dir [--root]

create the

ibgib --b2tfs-init --root --data-path=.ibgib --name=[optional-name] --dir-path=[path/to/dir]

synonyms: [--b2tfs-mkdir]

  • if existing "fs" tag is not created/found, will throw an error.
  • --name is optional override of --dir-path directory name
    • IOW will use dir name if --name isn't provided
    • if the dir name already exists, throw an error explaining using the --name option
  • you can look at fs tag to list fs roots
    • this is somewhat analogous to looking at repos (source/fork) & gists

So after this is run, we will be at the point where we have an fs-root ibgib that is dedicated to a composition of timelines. We now need the ability to compose these timelines in such a way where we can meaningfully "version control" the entire "repo".

I'm thinking we will use the "file" and "folder" names as rel8nNames but not necessarily to "file" and "folder" ibGibs. Or IOW we are going to add ibgibs - which do not necessarily have an ib like "file [filename] [n] [...]". but we do need a way when projecting onto an FS a way of maintaining the mapping.

This is because when we go and "import" files/folders into our ibgib space, we may want to import other non-file/folder items as well into the space. Remember these files live in an ibgib space that is not as restrictive as the FS subspace.

I'm thinking we will need a subspace mapping that maps rel8nNames to folder names. The "file" and "folder" rel8nNames will map explicitly to children to mimic existing fs-based vcs behavior (e.g. git). Then when we go to add in super-FS behavior (such as importing individual function/class timelines), we can still map back and forth to/from file system directory structures.

Here is what the tag that gets initialized on the tags special index:

ib: special tag fs-roots
gib: abc123
rel8ns: {
  x: [fs root my_repo^abc123, ..., fs root some-other-repo^abc123, ...]
}

The my_repo directory structure in the fs might look like this:

  • my_repo
    • dir1
      • dir1.1
        • file_a.txt
      • ...[other files]
    • dir2
      • file B.md
      • ...[other files]
    • ...[other dirs]
    • root-file1.txt
    • ...

note: these are example file/folder names not ibs with metadata attached. 1/2/a/b included for pedantic purposes

So this would map to an ibgib structure like this

fs_root my_repo tjp123^abc123
data: {
}
rel8ns: {
  folder: [fs_folder dir1^abc123, fs_folder dir2^abc123],
  file: [fs_file root-file1.txt type=text^abc123, fs_file text root-file2.txt^abc123]
}

b2tfs-activate-branch

b2tfs-add-branch

NOT IMPLEMENTED (YET?)

I may end up combining this idea with b2tfs-add-root-branch with a --root param.

  • RCLICommand.b2tfs_add_branch

  • the idea is to create branches of existing branches/snapshots/whatever i end up calling these kinds of things.

  • this is different than adding a root branch in that a root branch does not have a previous b2tfs item

b2tfs-diff

  • RCLICommand.b2tfs_diff

  • handle-b2tfs-diff Command Handler

  • provides a diff of the current FS state against what is contained in the target branch ()

  • params (exact names not guaranteed atow 01/2024)

    • --b2tfs-branch
      • if none, will use the current active branch
      • if no active branch, will use the first root branch
    • --apply
      • if set, will calculate the diff and subsequently apply it
        • in ibgib b2tfs, this means that new B2tFSItemIbGib timelines will be made and existing ones will be extended if different.
      • if not set, then the diff will only be calculated and shown to the user but not applied.

ibgib --fs--add-root [path/to/dir]

--b2tfs-cwd

NOT IMPLEMENTED. JUST THINKING ABOUT THIS...

ibgib --b2tfs-cwd

synonyms: [--b2tfs-pwd]

shows the current working directory when doing fs commands.

on mental shift from existing file/folder version control

Version control systems like CVS and variants, subversion, and of course the most widely used of our day git, were developed with one primary goal in mind: meticulously track changes to filesystem-based text files and the folder structure organizing them.

This is an extremely focused special case of what can be more generally seen as enabling timeline composition. The absolute most important mental shift is this:

Time is the domain - not files, not folders, not text.

In making this metonymous mental shift to a more general system, a few notes may be helpful.

there are no "repos"

A repository is itself not self-similar enough. How do we organize repositories? Today, we use PaaS's like GitHub, GitLab, BitBucket, Atlassian, etc. But these do not dogfood the timeline dynamics and essentially are kluged, out-of-band metarepos themselves.

Instead of "repos", Ibgib's general case timeline composition uses spaces. Very similar, there is the distinction of being able to create interspatial dynamics among spaces. This is somewhat analogous to what is currently done with DevOps which includes not only build steps but also even the package manager functionality. So we will empower ourselves to have both finer-grained semantic-level dynamics, like sharing individual versioned functions, as well as the macroscopic versioned workflows. All of this using the same metasystem, to enable metaversal dynamics.

simple repo step-by-step

(atow 12/2023 top-down, user pov, algorithmic notes while working through implementation)

right now i'm envisioning the b2tfs vcs to create different folders when branching (a root is a type of branch whose creation source is out-of-band). so when we first create a new root inside of a metaspace, i am thinking it will look like this for a "simple repo" folder:

my-repo/

we do a non-b2tfs init on this folder:

// metadata and data ibgibs, including one local user space (no name)
my-repo/.ibgib/*

we add a few files and folders:

// no changes
my-repo/.ibgib/*

// files/folders created
my-repo/b2r_main/file1.ext
my-repo/b2r_main/file2.ext
my-repo/b2r_main/subfolder1/file3.ext

at this point we have not synced any of the changes in the file/folder projection to the ibgib data, so now we do so. unsure of exact commands. perhaps something similar to existing vcs's or perhaps a simpler workflow. other vcs's can always be mimicked later if prudent.

// metadata and data ibgibs, including spaces and source ibgibs for projected files
my-repo/.ibgib/*

my-repo/b2r_main/file1.ext
my-repo/b2r_main/file2.ext
my-repo/b2r_main/subfolder1/file3.ext

at this point, file data is essentially doubled in this example as the b2r_main folder's files/folders all also exist inside .ibgib database as BinIbGib_V1 ibgibs.

now say we want to execute a B2tFS branch operation.

first, it should execute a check that there are no changes. if there are, then the branch operation fails and either the changes must be committed or rolled back (in the future should also be able to transfer changes to new branch with an explicit flag - otherwise this is an unexpected state). once this is taken care of, in order to branch, all b2 "main" root ibgibs will be copied (not b2r_main files+folders). this is done by getting the entire dependency graph of the single (in our simple repo example) B2tFSRootIbGib as well as all associated metastones (metastones are also ibgibs) for all timelines. these ibgibs (importantly, this leaves out the main B2tFSIndexIbGib and any space ibgibs, e.g., NodeFilesystemIbGib_V1) are then copied into the newly created "mybranch" space (not b2b_mybranch folder). Nothing is "replayed" or "merged" at this point because the "mybranch" space is fresh (guaranteed no conflicts), and no registerNewIbGib functions are needed because those are what generate the metastones. Once these exist in the new branch space, only then do we iterate through the graph and create all filesystem artifacts (folders/files) in the new "b2b_mybranch" fs folder.

After the branch op completes, our filesystem will look something like this:

// has new content ibgibs, as well as new mybranch space
my-repo/.ibgib/*

// b2r_main stays the same
my-repo/b2r_main/file1.ext
my-repo/b2r_main/file2.ext
my-repo/b2r_main/subfolder1/file3.ext

my-repo/b2b_mybranch/file1.ext
my-repo/b2b_mybranch/file2.ext
my-repo/b2b_mybranch/subfolder1/file3.ext

at this point, we should have to (nearly?) identical directories.

note: we can also mimic existing vcs behavior by replacing a single working folder, but why do this? the benefits of this separate folder approach are many, whereas the the replacement method can be confusing/scary - both for users and for tools (a hot reload local server for example). note that there is extra code to be maintained now that shows the current branch in people's commandlines/ide's. the drawback of increased disk storage in a world where space is so cheap seems arbitrary, especially since this is a legacy filesystem projection algorithm in the first place. we "should" be using a native ibgib "filesystem" in the future in which we have a os-native, global uuid-based key/value store where local content-addressed data is not duplicated.

now that we have a new branch, say we update/delete some files/folders by

  • updating file1.ext,
  • adding a new files newFileA.ext and subfolder1/newFileB.ext, and
  • deleting file2.ext.
// new content ibgibs, including new and updated B2tFSItem ibgibs corresponding to files/folders
my-repo/.ibgib/*

// b2r_main stays the same
my-repo/b2r_main/file1.ext
my-repo/b2r_main/file2.ext
my-repo/b2r_main/subfolder1/file3.ext

// b2b_mybranch changes
my-repo/b2b_mybranch/file1.ext (modified)
~~my-repo/b2b_mybranch/file2.ext~~ (deleted)
my-repo/b2b_mybranch/newfileA.ext
my-repo/b2b_mybranch/subfolder1/file3.ext
my-repo/b2b_mybranch/subfolder2/newfileB.ext

These changes are again synced to the appropriate ibgib timelines. This includes creating new B2tFSItem ibgibs for each new file & folder and performing mut8/rel8 transforms on existing B2tFSItem ibgibs.

note: we are not explicitly setting any paths here as the only path stored is in the B2tFSRoot ibgib, which keeps a relative path from the local metaspace. all other hierarchical pathing is done via B2tfsItemIbGib.rel8ns using the B2TFS_CHILD_ITEM_REL8N_NAME named edge.

when recursively traversing folder paths to sync/add files/folders, folders prefixed with b2r_ (root) and b2b_ (branch) are skipped.

note: these prefixes must be terse/cryptic to help mitigate legacy os pathing constraints.

ibgib - belief vs. knowledge, p vs. np

you are walking on a path towards your home. suddenly, you come to a fork in the path: one path leads to the land of truth and the other path leads to the land of lies. you have two guides, each from those lands. as such, one guide always speaks truths and one always speaks lies. you can ask one of them one question. what do you ask?

this is a variant of a classical thought experiment that i have been asked since as early as i can remember. the standard "solution" itself is to ask either guide how the other guide would answer. (there is an equivalent variant with a single guide and you don't know which land he/she comes from, where the "solution" is for the guide to ask him/herself, i.e., "how would you answer if i would ask you...").

but there are intrinsically interesting qualities of this thought experiment. this mostly resolves around the "definition" (which implies a past tense solution) vs. the ongoing "defining" of "solving" itself (present progressive tense without necessarily itself being resolved).

for example, take the sock drawer question: say you have a sock drawer with two black socks and two white socks in it. how many would you need to blindly pull out in the dark to guarantee a matching pair? again, there is the meta question of our initial question statement: the "say you have" part. how do you know you have that state? even if you were to check, how do you know that state hasn't changed? how many people would agree that each white sock is still white? what if it was in the machine with a red sock and got dyed? or how many washes until it was frayed beyond being a sock?

in both thought experiments, and i say in all thought experiments, there is always the conscious decision to apply a metric to quantize thought.

tabling knowledge past tense, ibgib however focuses on the union of both guides:

i believe g/God is being.

ib G/g ib. or ibG ib. or ib Gib. or ibgib. or ibGib...

to say that i "know" something, is now shorthand for "i am believing" some state. "i" provides a local space. g/G and/or g/Gib provides some ontological state, implying that it's above me, as "i" can only get a metric projection of it into that local space. this includes statements (including questions) that local space, i.e., "myself".

the effect of this paradigm shift from "knowledge" (past tense) to this marriage of present and past tense of believing is to focus on infinitely-branching time-based dynamics. instead of just reasoning in terms of "space", we are now working with the analog to "spacetime".

so let us revisit the fork in the road thought experiment. each word in this formulation is now itself a timeline. indeed, "word" itself can be a misnomer here in that other words may themselves be more apt, according to some metric, such as combining two words into a single one, e.g. a contraction. so when i say "word", i mean the logical construct not necessarily the reified text used to represent that logic.

but with this framing, how can we possibly make progress towards might be thought of as a "solution"? well, here is my "solution". i myself am the one doing the solving. while i still live, the solution can never be past tense. so instead of providing the image of a "solution", i focus on words that provide dynamics to iterate on to solving processes. while i am still living, i continually iterate on the process of defining.

Package Sidebar

Install

npm i @ibgib/ibgib

Weekly Downloads

53

Version

0.0.148

License

ISC

Unpacked Size

8.95 MB

Total Files

1880

Last publish

Collaborators

  • wraiford