.sinatrah

410,757,864,530 DEAD COPS

[ who ]

hi :3
certified hobbyist who builds things (because the act of building matters even if the output doesn't).
most of it is random personal stuff and stays on my machine. outside the code, most of my thinking goes toward philosophy (some working mix of absurdism, materialism, and nihilism) and politics (politically left in the sense that most of what constrains people isn't natural or inevitable but constructed and maintained).

preference for: flat files, local-first, stdin/stdout, no daemons, no accounts, no telemetry. not ideology — just what survives longest without maintenance.

[ what ]

  • wss.chat [go] fully server-driven chat. users, roles, polls, commands, moderation. no client-side state. server owns truth. websocket transport only.
  • steg [go] steganography tool. hides messages in plaintext using zero-width characters. encodes arbitrary payloads into unicode whitespace. survives copy-paste. undetectable to casual inspection.
  • trek [go] minimal CLI task tracker. flat file, no database, no sync. stdin/stdout only. tasks stored in a single annotated text file you can read without the tool. deliberately local.
  • sig [C++] command signature differ. compares function signatures across source versions. written to catch breaking API changes without running a build. parses headers directly, not binaries.
  • clog [sh] structured changelog generator from git log. opinionated format, zero config. reads conventional commits, outputs plaintext or markdown. fifty lines of shell.

[ how ]

  • golang backend, realtime systems, static-first architectures, CLI tooling
  • C++ performance-critical tools, parsing engines, low-overhead design
  • C systems programming, embedded constraints, no-stdlib environments
  • shell automation, glue scripts, POSIX-compatible toolchains
  • HTML/CSS zero-javascript interfaces, semantic structure, static delivery

blog

template blog post

complexity is the default failure mode

most people add until something works.

i remove until only necessary parts remain, then question those too.

/path/for/thing.txt
sudo apt install blog

log

removed another dependency. nothing broke. suspicious.
considering deleting the blog entirely
most problems are self-inflicted architecture
rewrote the same tool again. smaller this time.

code

minimal parser

/src/parse.c
#include <stdio.h>

int parse(char *input) {
    return input[0];
}
notes

this should probably not exist

zero-width encoder

/src/steg.go
package main

// encode encodes data into zero-width unicode characters
// interleaved with the cover string.
func encode(cover, data string) string {
    zw := []rune{'\u200B', '\u200C', '\u200D', '\uFEFF'}
    bits := toBits([]byte(data))
    out := []rune{}
    for i, ch := range cover {
        out = append(out, ch)
        if i < len(bits) {
            out = append(out, zw[bits[i]%4])
        }
    }
    return string(out)
}
notes

payload survives most copy-paste paths. stripped by some sanitisers. test your target environment before relying on it.

flat task store

/src/store.go
package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
)

type Task struct {
    ID   string
    Done bool
    Text string
}

func load(path string) ([]Task, error) {
    f, err := os.Open(path)
    if err != nil {
        return nil, err
    }
    defer f.Close()
    var tasks []Task
    s := bufio.NewScanner(f)
    for s.Scan() {
        line := s.Text()
        done := strings.HasPrefix(line, "x ")
        text := strings.TrimPrefix(strings.TrimPrefix(line, "x "), "- ")
        tasks = append(tasks, Task{Done: done, Text: text})
    }
    return tasks, s.Err()
}

func save(path string, tasks []Task) error {
    f, err := os.Create(path)
    if err != nil {
        return err
    }
    defer f.Close()
    w := bufio.NewWriter(f)
    for _, t := range tasks {
        prefix := "- "
        if t.Done {
            prefix = "x "
        }
        fmt.Fprintln(w, prefix+t.Text)
    }
    return w.Flush()
}
notes

file format is human-readable without the tool. lines starting with "x " are done. everything else is open. no IDs, no timestamps, no schema.

shell fragment

/bin/run.sh
#!/bin/sh
while true; do
    sleep 1
done

changelog from git

/bin/clog.sh
#!/bin/sh
# clog — generate a changelog from conventional commits
# usage: clog [from-tag] [to-tag]

FROM=${1:-$(git describe --tags --abbrev=0 2>/dev/null || echo "")}
TO=${2:-HEAD}

RANGE="${FROM:+$FROM..}$TO"

echo "## changes\n"

git log "$RANGE" --pretty=format:"%s" \
    | grep -E "^(feat|fix|refactor|remove|docs)" \
    | sed 's/^feat: /+ /' \
    | sed 's/^fix: /~ /' \
    | sed 's/^refactor: /% /' \
    | sed 's/^remove: /- /' \
    | sed 's/^docs: /# /'
notes

reads conventional commits. outputs to stdout. pipe to a file or use as-is. fifty lines was a generous estimate — it's less.

[ projects ]

yappifier

word-based substitution cipher. converts each character into a randomly selected word from a large shuffled list. the seed is the password — same seed encrypts and decrypts. herring frequency and filler count add noise to obscure character boundaries.

requires alpha.txt served alongside this file.

[ io ]

input
output

[ config ]

index map
ready.