The public repository publishes its own server image, ghcr.io/nathannncurtis/dokkit-server
Both licences at the repository root
Licence files: the libraries and the phone apps are Apache 2.0
Licence files: the server is AGPL 3.0 and the program Apache 2.0
v0.1.47
A Slack or Discord webhook address gets a message in their own format, when an issue opens and when it closes
The program builds for the browser as dokkit check without running the checks, from the same parsing and rules
Phone apps: titles follow the theme in dark mode, and the need-you card lists only what it counts
Specs that only described code already written are gone; the dokkit.toml format and the MCP move to docs, and code no longer points at doc files
15 October
v0.1.46
The database only counts as down after three minutes in a row without an answer, and the phone sender builds its snapshot once per round instead of twice
v0.1.45
The self-check asks the database over a connection of its own, so a busy or stuck pool no longer pages that the database is down
v0.1.44
Add a machine gives Windows one line, irm <server>/add/<token> | iex, which hands out the script while its token is unused; the script as a file is a link to click
v0.1.43
Add a machine gives Windows one script: it fetches the program from the server with a one-use enrolment token, checks its signature, enrols, installs the service and the updater, checks it reports and offers to delete itself
v0.1.42
The Windows server's installer is back to the generated service name: Erlang's service wrapper reads its settings only under the name it made, so a service made under dokkit-server cannot start
v0.1.41
The server's Windows service shows as Dokkit server, since the program's service already holds the display name dokkit; a failed install starts the server's service again, in the installer and in the updater
14 October
v0.1.40
The installer waits for a removed dokkit-server service to be gone before making it again, and the scan and Found treat dokkit-server as Dokkit's own
The Windows server keeps one service name, dokkit-server, across upgrades, and an upgrade removes the generated names earlier installs left
v0.1.39
decimal 3.2.0, for its advisory on unbounded allocation in Decimal.round
v0.1.38
Library fixes from the audit: PHP stops sending errors at the first failure, Java and .NET wait at most 5 seconds at exit, and Swift sends kept error reports one at a time and stops at the first failure
Phone fixes from the audit: the relay takes 12 uploads a minute so pairing and removing a phone are not refused during an incident, a new relay address pairs phones again, an unchanged snapshot is uploaded at most every two minutes, and the iOS app refuses redirects from the relay
Server fixes from the audit: a report or envelope is refused before it is split into more than the limit, a huge envelope timestamp no longer loses the envelope, a late update result no longer clears a newer approved version, a group cannot be taken over by enrolment, X-Forwarded-For is trusted only from loopback, snoozed issues stay quiet when they reopen or their machine returns, a blanked limit closes its issue, loaded-back log months are archived again and matched by month, job and work runs older than 90 days are pruned, the month archive streams in its own task, and settings and slug helpers have one copy
Program fixes from the audit: process checks match long names, checks set in the interface keep command_has, at_least, date_from, numeric status and their interval, job secrets in env vars, -p, URLs and Bearer are masked, a run still in progress is not reported, a BOM no longer hides the first JSON line, a file path is not read as a certificate address, the scan finds process paths under Local Service, and the updater refuses a hard-linked file, syncs before rename, times out a stalled download, drops a result the server refuses, with rollback tests and one copy of xmlEscape and sameFile
v0.1.37
The updater starts a download again for a minute when the connection is cut or the server answers 5xx, so a machine fetching while the server restarts into the same release is not failed
v0.1.36
A program that runs as root on a cron-scheduled machine, as on the NAS, starts its updater itself when an update is asked for, so the NAS updates within seconds too
v0.1.35
Puts back the files a whole-tree format rewrapped in the last commit; only the updater check time stays
v0.1.34
The server records when each machine's updater last checked in, and the machine page and API show it to the second
v0.1.33
The updater keeps trying to report its result for a minute, so a machine that updates while the server restarts shows as updated within seconds instead of on its next timed check
v0.1.32
An update request that lands within 30 seconds of the updater's last check waits out the gap and checks, instead of being dropped until the next timed check
v0.1.31
Log lines can be moved by message text and level as well as by field
v0.1.30
Stored log lines can be deleted from a service by app name, text, level or time, never without a filter
On Windows an update request reaches the updater through an Application log event that starts its task, since Windows would not let the program start the task itself
v0.1.29
The program logs what happened with each update request and sends the same answer to the server, and a machine's page shows its last update request and how it was answered
v0.1.28
A connection the server stops reading is dropped and a new one opened: the work poll and everything else use separate connections, HTTP/2 pings and write deadlines catch a dead one, and two timeouts in a row replace the connection pool
v0.1.27
Log lines can be moved from one service to another, how many months of logs stay live and whether older months are archived or deleted is a setting, the chosen machine on Found scrolls into view, and a machine that stops reporting is planned on the sweep's own clock
A Windows scan lists the scheduled tasks its own account cannot see from a list the updater writes once an hour, so tasks set up by an administrator are found
13 October
v0.1.26
Update starts within seconds: the server tells each machine's program over its open work connection, the program pokes its updater through a task or file it may only start, and the updater keeps its own schedule current; the five-minute check stays as the fallback
The slow stats test waits for the stats fetch to finish before its folder is removed, so it no longer fails on Windows when the fetch writes to the spool during cleanup
v0.1.25
On macOS the scan finds listening ports through lsof, with the address each listens on
v0.1.24
The web interface shows one progress screen while machines update, Apps have their own page and sidebar entry, and each machine has its own page with everything known about it
v0.1.23
The server keeps each machine's newest process list, 24 hours of the top ten by memory and by processor, and a snapshot with memory, processor and stopped-service issues; a Processes card on the machine's page, two read calls and two MCP tools
Each minute the program sends the machine's process list: name, path, process number, parent, memory and processor share, from the system's own process list without opening any process or reading a command line
v0.1.22
A found port is checked at the address it listens on when that is one specific address, so a program bound only to its public address is no longer reported down on localhost
v0.1.21
On a QNAP the firmware's own partitions and each storage pool's system volume are not reported as disks, so a NAS's fullest disk is one that holds data
Android app: the spoken summary check matches the iOS wording, which has no closing full stop
Android app: Home follows the iOS app's wording and rules (needs-you and soon issues in the top box, the planned-downtime line on closed cards, last reported on a down machine, Show fewer, the fullest disk named)
Android app: the empty-snapshot check reads its middle dot as UTF-8
4 more changes
Android app: Home reaches the shared issue rows through Screens
Android app: one Home screen with a top box, machine cards with meters that open in place, and a first-run screen, with the logic and its checks in the plain Kotlin layer
Android app: the web interface's own teal and ember colours, portrait only, and the window hidden from the recents screen
Android app: a read-only Compose view of a paired Dokkit server, with its logic in plain Kotlin checked against the spec's test vectors, and an unsigned release build the workflow keeps
v0.1.20
iOS app: one Home screen that says whether anything needs attention and whether the hardware is up, with each machine a card of meters that opens in place, and a first-run screen that says where the code is
iOS app: the web interface's own colours (teal on white, orange on the Ember brown) and its own icon, a plain cover while the app is unlocked but not in front, and portrait only
The unlock gate asks once each time the app comes to the front, so cancelling Face ID leaves the Unlock button instead of asking again.
The iOS app reads its signing team and bundle id from Signing.xcconfig, which takes an untracked Local.xcconfig when there is one, so both survive regenerating the project.
2 more changes
The iOS app has an icon: the white D and dot on the web interface's brand colour.
Phone apps: a script packs the iOS app as an unsigned ipa, and the workflows that build each app by hand keep the file
v0.1.19
Relay: dokkit relay holds a server's newest sealed snapshot in a mailbox and hands each phone its part, behind a reverse proxy that has the certificate
iOS app: the checksum word is read in plain steps the older compiler accepts, and the models and screens follow the server's snapshot (chart with gaps, what was left out for size)
Phones: the server keeps a relay setting and paired phones, seals a snapshot of what the phone app shows and uploads it each minute and after an issue changes, with a Phones section in Settings and the same calls in the API
iOS app: a read-only view of a paired Dokkit server, with its logic as a Swift package checked against the spec's test vectors, and a workflow that builds it on a Mac runner when asked
v0.1.18
Planned downtime can be scheduled on a machine's page: once at a date and time, every day or on chosen weekdays, in the night's time zone; a scheduled window holds for its whole length, and the API and the AI tool list, add and remove schedules
v0.1.17
Log search pages again: a log line's id is a number, and the cursor took it for text, so any search with more lines than its limit answered 500
11 October
v0.1.16
The planned downtime table is made after the machine routing migrations
The planned downtime band reads on a phone and the reason box fits its words
A machine, a person or a tool can plan downtime for a machine: it opens no issue for going silent or for its checks failing until the time is up, the window ends early when the machine is back and has reported, and dokkit quiet tells the server from a script
Alerts take several channels for one thing, a machine that stops reporting has its own channels and night setting, the night is kept in a time zone so daylight saving is right, and a PagerDuty test alert stays open for two minutes before it resolves
v0.1.15
Inbox cards share one width, machine names are no longer cut off in the issue list and on the other pages that show them, and each issue says its service, check and kind of check
The scan never proposes Dokkit's own service, unit, task, timer, daemon, cron line or containers, the server drops them from an older program and removes the ones already waiting, and a start-up step stops watching the server's own Windows service and its Postgres
v0.1.14
Found shows machines in a list beside the chosen machine's findings, in sections by kind with Watch all and Dismiss all, the choice in the address, and a keyboard-driven list
v0.1.13
Found hides what the operating system ships unless Show system services is on, counts what it hides in total and per machine, and shows where each finding came from; the proposals API and tool take system and answer hidden
Every finding a scan sends says if it is the operating system's, installed by other software, or set up by a person, and gives the fact it decided from
v0.1.12
dokkit import seq says on stderr which side failed and how to continue, retries a lost connection or a 5xx for ten minutes, prints progress once a minute, and has no rate cap by default
An app key has no limit on how fast it sends: the intake calls and the Seq door no longer charge a bucket or answer 429, which now comes only from the alert test and the sign-in throttle
v0.1.11
A person's own token can no longer remove that person, through the API or the MCP tool
apply help says it sends DOKKIT_KEY or else the machine key, and that an app key declares its own service
declare has one doc for both its machine and app-key cases, so compiling no longer warns about a redefined doc
The IPv6 listener decision is a public function with a test: an IPv4 wildcard address gets a second listener, any other address gets none
40 more changes
Sample estate runs again without the removed Tasks, shows a found scheduled job, a run in progress, a dependency, a staging sibling and machine readings, and takes its database and port from the environment; the Tasks page styles go
Enrolment: the spent token records which machine it became
First install checks the release signature: get.sh, get.ps1 and the Windows server's install.ps1 fetch SHA256SUMS and SHA256SUMS.sig, verify the Ed25519 signature against the release key and then the file's hash, and take another release folder (and key) as a parameter; updater rehearse is in help and the usage text, and updater install on Windows is documented as needing the service first
Alerts go to people: each person has their own destinations, and a check, a service, a rule or the default names who is told; the digest goes to each person with what was theirs, the iMessage card says where sending stands, and the alert spec now matches the code
Dokkit's own row pages when it stops taking reports or cannot reach its database, and pushes for lesser trouble; the two channels are settings on the Alerts page
Add a machine: a Copy button beside each line and Copy both, tokens made and not used listed with time left and Revoke, the page names the machine a token became, and one token life of 4 hours for the page and POST /keys (hours sets up to 72)
Found page and scan polish: repeating tasks as a stepped cron line, the conversion note, Look again rows laid out for each machine
Appearance: the dark base and the accent colour can be chosen in Settings beside the theme, with a live preview; every accent keeps 4.5:1 text contrast on its buttons and badges in light and in every dark base
dokkit import seq: copies a Seq server's stored events into Dokkit, oldest first, with their own times, resumable, with a dry run
Conformance run: each library's smallest program against a local Dokkit server, checking what the server stored for production and for another environment
Recovery codes: turning on two-step shows ten one-time codes once, the code step accepts one in place of an authenticator code, and the two-step page counts what is left and makes a new set
Pages: a run in progress shows its done and total with a bar on Jobs and the service page; Add a dependency on Everything
API depth: lists page by cursor with q, machine, service, environment, from and to; a service answers with its versions, deploys and facts; issues by state with history; an error group lists its reports; proposals accepted or dismissed together; job runs carry done and total; POST /dependencies; the MCP in step and its table complete
Found keeps jobs, containers with a published port and sites with an address; an accepted job waits for its first report and says how its runs get reported; Look again asks a machine to scan, through the page, the API and the AI tool
Seq's address: an app that logs to Seq moves by changing its server URL and API key; CLEF and Seq's JSON events are stored as that app's log lines through the same path as the report door
http check: an optional status (a code, a range or a list) is the answer that counts as healthy; without it anything under 400 still passes
JavaScript library: console output during sending is not fed back, a failed error post is kept and retried apart from log lines, lines cut at 64 KB, report bodies gzipped where CompressionStream exists, announceVersion turns off the deploy line, a non-production environment is on every line
Go library: the slog handler skips records logged while the library is sending, lines cut at 64 KB, an error post answered 429 is retried, AnnounceVersion turns off the deploy line, a non-production environment is on every line
Process check: at_least sets the fewest processes that is healthy, fewer is degraded and none is down, and the value is the count; the spec says which processes each system lets an unprivileged account see
Shell library: the deploy line goes with the first report, dokkit_stats and dokkit_deploy, an error post is repeated when nothing reached the server, lines cut at 64 KB, gzip where available, a non-production environment is on every line
PowerShell library: a failed error post is kept and retried, lines cut at 64 KB, report bodies gzipped, Send-DokkitStats, a start option turns off the deploy line, stack paths relative to the script's folder, a non-production environment is on every line
Scan finds scheduled jobs to watch: Task Scheduler tasks, cron entries, systemd timers and launchd jobs with the schedule read as UTC, last run, last result and command line; the program reports runs of Task Scheduler tasks and systemd timers from the system's own record, scans once a day and answers dokkit:scan; the scan keeps container ports and IIS site addresses
Stats: a key_env that is missing or wrongly named makes no request and is said as a warning for the service, not as the service being down; stats are fetched on their own goroutine so a slow address holds no check back
dokkit doctor: a certificate pin mismatch, an unresolved name, a refused connection, a timeout, a TLS failure, a wrong key and a clock that is off each read differently with the one thing to do, and a Mac's background copy held by local network privacy is named
PHP library: a failed error post is kept and retried and no longer stops log lines, lines cut at 64 KB, report bodies gzipped where zlib is loaded, a start option turns off the deploy line, a non-production environment is on every line
Elixir library: a failed error post is kept and retried, lines cut at 64 KB, stack paths relative to the app folder, a start option turns off the deploy line, a non-production environment is on every line
Expiry is warned 30 days ahead: the test uses the exact time left, not days rounded up
Rust library: log_fields sends fields, the exit and panic flush is bounded to five seconds, a panic is an error report with type and stack, a failed error post is kept and retried, lines cut at 64 KB, a start option turns off the deploy line, a non-production environment is on every line
dokkit check refuses what the server refuses at declare: service id and kind, job ids and schedules, fail_after, and the stats and logs settings; the same cases run on both sides
Java library: a failed error post is kept and retried apart from log lines, lines cut at 64 KB, a start option turns off the deploy line, a non-production environment is on every line
.NET library: the library's own sending is never fed back into the logging provider, a failed error post is kept and retried apart from log lines, lines cut at 64 KB, a start option turns off the deploy line, a non-production environment is on every line
macOS service: dokkit service install|uninstall|start|stop|update runs watch as a LaunchDaemon under a hidden _dokkit account, moving the person's own setup and turning their LaunchAgent off
Swift library: a failed error post is kept and retried, lines are cut at 64 KB, a start option turns off the deploy line, a non-production environment is on every line, tests added
Python library: the stock handler sends extra fields and exception type and stack, dropped lines are counted and sent, enabled() reports whether it is on, lines cut at 64 KB, an error report refused with 429 is retried, a start option turns off the deploy line, a non-production environment is on every line
dokkit apply from CI: an app key may declare the one service it belongs to, with jobs and beat or custom checks only
Nothing is lost: a log or spooled batch the server finds too large is halved down to one line, refused lines alone are set aside with the reason, a server error never skips log lines, and what is cut or set aside is counted and reported
macOS readings: memory used and processor use are read from vm_stat and top, counted as Activity Monitor counts them, with the file cache left out
Environment from the libraries: a line, an error or a Sentry event from another environment lands on its own service that never alerts; a declared service keeps the environment its file gives it
Machine history: a machine's own disk, memory and processor numbers are readable over time in the API, the machine page and the series tool, as charts with the limit drawn, the disk that is filling first
Python and Go libraries: the app's folder is the program's, a failed error report is kept, the exit flush has a time limit, and a blank address or key given to start is off
v0.1.10
Two-step sign-in: the setup page keeps one secret until it is confirmed, so a reload or a second tab shows the QR code already scanned; two-step state from before is cleared
The add-a-machine test accepts the first second of a new token, when four hours are still whole
Everything and Found: what runs on a machine is indented under it, with a guide line, a stronger machine heading, a rule between machines, and an empty line for a machine with nothing on it
Disks are reported once: the volumes of one macOS container, bind mounts and subvolumes of one device are one disk, and the macOS helper volumes, Recovery and snap loop devices are left out
1 more changes
Disk forecast: needs 4 days of readings and a rise in the whole week and in each half, so one step up no longer predicts a full disk; over-limit disk issues close when the disk stops being reported
v0.1.9
Updater on a QNAP lives on the data volume, not the memory disk: its program, config and state are kept in a root-only .dokkit-updater folder, found again from its crontab line; the crontab is loaded without QNAP's crond restart, which rewrites it; dokkit watch --background takes a lock so two starts cannot make two programs
Updater on macOS: a LaunchAgent restart waits out launchd's throttle so a rollback restarts the old file, and a program path that is a link is refused before anything is copied
Updater: the rehearsal on Linux and macOS seeds its stand-in files as runnable and prints its log once, and the QNAP crontab edit is tested against a scratch file
Process check: on Windows the executable path is asked of the system by process number, so processes of other accounts are seen without opening them
8 more changes
Tokens: the Add a machine page asks how the machine will run and shows the right commands with a copy button, a countdown and the machine when it enrols; a made user token has a copy button and its next step
Process check: command_has also matches a piece of the executable path (Windows) or command line (Linux, macOS), so one app's python.exe can be told from the rest
Service update: an old log that cannot be read is left behind instead of stopping the update, a refused file is named unless the prompt is not elevated, the new folder is locked before the key is copied in, and a failed update starts the service again
Updater: also works on Linux and macOS, installed once by root, with a systemd timer, a LaunchDaemon or a root crontab line, and restarting the program as a system or user unit, a LaunchAgent or a plain background process
Remove tasks: Dokkit only monitors and updates itself, so the Tasks page, the task API and MCP tools, the program's task commands and the task tables are gone; the work channel stays for updates and iMessage
Alerts page: a test checks that Send a test takes the Mac and address chosen in the form without a change event first
Service page: the Held version form stays inside the Watching card, with Save beside its field at every width
Server: on Windows it answers on IPv6 as well as IPv4, with a second listener, since one IPv6 socket there takes no IPv4
v0.1.8
Sign-in: a person can turn on two-step sign-in, so the password is followed by a code from an authenticator app that works once
v0.1.7
Certificate: a service that cannot be reached is reported with the reason
v0.1.6
Certificate: the challenge record is looked for on the zone's own name servers, since a caching resolver keeps an early miss; the release test's scratch folder cannot collide with one left from an earlier run
Certificate: the server gets and renews the uploaded certificate by itself from Let's Encrypt, proving the name with a DNS record at Cloudflare
Certificate: a second certificate for a real name is put in place through the API and Settings, chosen by the name the client asks for
v0.1.5
Apps: an app that runs on many machines is added by name, under no one machine, and gets its key
7 October
v0.1.4
Updates: the server holds signed releases, an owner approves one for a machine or all, and the machine list shows what each updater is on and what it was asked
Program: dokkit updater rehearse does one real check, with the real signature and hash checks, into a folder of its own
Program: an updater that installs signed releases approved in the interface, and dokkit version
Alerts page: every block has its own Save beside its fields and says there what happened, and Send a test saves what is typed first
2 more changes
Windows installer: an upgrade copies only the files that changed, so a file Windows still has open is left alone when it is the same
Windows installer: the port mapper is stopped before the server's files are replaced, and a file still in use is waited for
v0.1.3
Alerts: iMessage through an enrolled Mac and SMS through Twilio replace the text channel
Program: dokkit imessage lets a Mac signed in to Messages send an iMessage when the server asks, and test sends one now
Program: a Windows service update leaves the service's account as it is
Windows installer: refuses, before changing anything, when the server's folders hold the program and no server
1 more changes
Program: on Windows the service keeps to Program Files\DokkitProgram and ProgramData\DokkitProgram, moves an install from the server's folders by copying only its own three items, sets permissions on the folder once and resets what is inside, and refuses a folder holding anything it does not recognise
v0.1.2
First screen: an issue of Dokkit's own, which has no machine, no longer breaks the last-day list
Program: the Windows service runs as Local Service, may write only its spool and log, fetches no update for an administrator to run, and install waits until it is running
Program: a service or process this account may not ask about is not reported as stopped; nothing is sent for it and dokkit check says so
The favicon the page links to is served: a digested file at the root has its hash in its name
4 more changes
The server's name is kept in lower case, so the live connection is accepted from a browser when the machine's name is in capitals
Windows installer: the service is set up under the name Windows knows it by, each step shows what went wrong, and the install is not done until the server answers
Windows installer: Local Service is set without a password argument, and a first install that stopped partway still prints its setup code
Windows installer: initdb drops its administrator rights, so the person installing is named on the data folder and the password file until it is done
6 October
v0.1.1
Windows installer: with a certificate of its own, the server's port is let through Windows Firewall
v0.1.0
Server listens on IPv4 on Windows, where an IPv6 socket takes none; a failed build skips the release without failing the run; files assets.deploy writes are ignored
Tests: missed-job detection is checked at fixed times across midnight, month and year ends, and the test that failed in the last minute of an hour no longer reads the clock
Libraries: the Java and Elixir handlers drop only their own sending, and the last review's fixes
Program: dokkit folder says where apps live, a crash-looping unit is down, and the last review's fixes
130 more changes
Review round: a failure that comes back always alerts, snooze and number carry over, a moved destination drops its secret, destinations are checked, and the parity test checks scope
API: every action the interface has, with an MCP tool for each, and a test that fails when a new one has none
Libraries: review fixes. No handler can feed its own sending back in, the Java library has a package, and install lines work from a checkout
First screen: fewer hour labels on a phone
Program: review fixes for the Linux service, slow checks and help, and a restart is told to the server
Review fixes: a warning that becomes a failure pages, forms keep what was typed, opened rows stay open, counts agree, routing and rules merge, held alerts respect snooze, and MCP answers are marked as data
First screen: the last day, one lane per machine and a cell per half hour, from issues and a record of when each machine was heard from
Alerts: a night for the whole server, a service can wait for morning, and job timing can be changed in the interface
Server: a disk forecast and a job that ran long go under Soon, a missed job says when it last ran, scans keep scheduled tasks and systemd services
First screen: Needs you, Soon, Not watched and Snoozed, rows that open in place, a count of what is fine, and other environments kept apart
Libraries: shell can capture, Python has log, console, PSR-3 and log-crate handlers, and every library has a package file and a README
Program: an http check can be slow without being down, dokkit service works on Linux with systemd, and the help says only what is true
Releases: a tag builds the image, the program for six systems and the Windows server zip, each with a SHA-256; get.sh and get.ps1 put the program on a machine
Server: the piped Windows install reads the checksum file as text when it arrives as bytes
MCP: a tool for everything the API can do, offered by the token's scopes, with the managing ones marked destructive
Settings: a token that can do everything is asked for on its own, with the address typed and a box ticked
Site mock: an API reference drawn from a new OpenAPI document, a command-line reference from the program's own help, what an agent does with a token, and motion
Program: dokkit help lists every command, and dokkit help <command> says more about one
Server: the download check hashes with .NET, which every PowerShell has
Server: the piped Windows install checks every download against a SHA-256 before unpacking it
Server: the Windows installer also runs piped from the site, fetching the release and a Postgres
Server: one command installs it on a Debian or Ubuntu VPS, with its own certificate
Interface: the dark theme is Ember, warm charcoal with a tangerine accent
Tests: an emptied bucket stays empty for the length of the test
The envelope door has a test for a body that is not valid gzip
A log file is known by its first line and its own identity
A task is pinned to every script it names, re-sent when one is edited, and refused where others can write
A body that is not valid gzip answers 422 with the code bad_gzip
Two log files that start with the same line keep separate read positions
A task is accepted as its command, its file and its script together
Server: the sweep steps fail apart, a settling server stays quiet, and the watch fixes are tested where they act
Libraries: a panic in a logged error, a panic in a job, an http address check, error retries and refusals are handled
Windows install: checks every security step, locks the service's registry key, restarts through the service wrapper, grants the archive folder, and can be rerun after a half-made Postgres
Libraries: PHP and PowerShell retry within the flush, PHP warns through error_log, the JavaScript library loads without top-level await, and smaller path, byte and number fixes
Intake: only data errors refuse a line, errors and deploys are cleaned, a token made for a machine allows re-enrolment, app keys leave enrolled machines alone
Sign-in attempts are counted before hashing, a changed password ends open pages, and every list page reloads at most once a second
Libraries: own frames default to everything but the JDK, loopback means exactly 127.0.0.1, errors are built on the sender thread, only reports are retried
Program: loopback is decided by address, refused checks report down, the install re-owns everything in its folder, and the lists survive a reinstall
Server: restores note the month before loading it and undo the note on failure, only a restored month is dropped without a file, and log partitions are re-bounded in UTC
Windows install: runs as Local Service, locked-down folders, a fresh cookie, https from a certificate, repeatable after a failure, and keeps earlier settings
Docker: pinned base images, a health check, and a port published on this machine only
Server: settings.env survives a byte order mark and trailing spaces, PHX_HOST is required, and a service logs to a file
Server: a database that is slow at boot no longer keeps the server down, and machines get time to report after a restart
Server: the release opens no Erlang node to other machines
Program: a resent log batch keeps its id, set-aside batches are counted across commands and bounded by the cap, and a skipped log chunk is reported
Libraries: Go and Rust send the same batch id when a batch is tried again
Libraries: Elixir sends from its own process, drops what cannot be encoded and checks the certificate
Tasks: a bare name in the task's folder still runs, a task that leaves something running still succeeds, a stuck run keeps its output, a stale fetched copy is removed, and one file reached two ways is one file
Server: a token's scope follows the matched call, not the path spelling; log notes, closed issues and MCP issue calls answer like the rest
Libraries: PowerShell keeps zero values and empty messages, restores the outer job after a nested one, asks for TLS 1.2, keeps paths relative
Port 465 mail connects over TLS with verification, alert addresses are checked when saved and by resolved address, a reopened alert gets its attempts back, the digest reads each limit once
Server: intake refuses one bad line instead of the batch, limits app keys, keeps machine keys exclusive, and reads ping bodies raw
Libraries: shell survives set -u and set -e, keeps the key and body out of ps, rejects arguments that would add fields, gives each run its own id
Libraries: Swift resolves its host name off the caller's thread, keeps http:// off, bounds its queue by bytes, and retries a failed batch
Libraries: PHP sends a valid batch id, stops at the first failed request, keeps millisecond times, repairs invalid UTF-8, finds its own frames correctly
Libraries: Rust finds the host on Linux, keeps stats on one line, reports a panicking job and sends less path
Libraries: .NET keeps http:// off, bounds its queue by bytes, retries a failed batch, and finds the app's frames and logs safely
Libraries: JavaScript works without crypto.randomUUID, times out and never stacks requests, sends uncaught errors before exit, reads Firefox and Safari stacks, names its host
Libraries: Java keeps http:// off, bounds its queue by bytes, retries a failed batch, and reads frames and hostnames safely
Server: one bad schedule no longer stops the sweep, a restart no longer pages, and dropped checks, stale runs, batches and container hosts are cleaned up
Libraries: Go resolves log values, copies lines when queued, bounds the queue by bytes and retries a failed batch once
Libraries: Python restarts its sender after a fork, drops only the line it cannot serialize, keeps paths relative, refuses plain http to other hosts
Server: sign-in is limited per name and per address, sessions expire and sign-out ends copies, and a password can be changed
Libraries: PHP sends the batch id in the dashed form the server accepts
Program: checks and logs run on their own clocks, restarts and remote checks need local leave, files stay in their folder, disk use is from bytes, self-signed certificates are read
Program: the Windows install refuses a ProgramData folder someone else made first
Server: archiving never writes over an existing file, restores are atomic, partitions are bounded in UTC, and lines a year or older are stamped on arrival
Program: the spool and log tail survive bad batches, report their drops, and jobs are reported under their service
Tasks: a repeated name runs from neither file, system runs need the machine's own say, results are retried, a timeout cannot hang the loop, and a fetched update is hashed
Server: tokens, logs and issue calls follow the spec
Tests: the task run is checked, and the digest suggestion counts real relapses
Server: alerts retry once a minute, blank settings use defaults, mail needs TLS, alert addresses must be public https, digest marks only what it sent
Cut what the audit found: the signature reader, the scope lists, repeated 404 answers and three setters
Libraries: Rust copies a run's values instead of rebuilding them
Server: the install script sets up a Postgres of its own, or uses one that is already there
Tasks run under an ordinary account unless accepted otherwise, and an update is fetched, never self-installed
Server: a Windows install script, and settings read from a file a service can see
Machines: fix the test of the built-in disk limit
Machines: disk and memory are watched against limits on the Alerts page, with nothing declared
Program: task list says what is accepted and which account tasks run as
Libraries: a Microsoft.Extensions.Logging provider for .NET
Dokkit's own row: whether reports are arriving and whether the archive folder can be written
Notes on an issue from its service page, and archived months load back from Settings
Versions: an app on many PCs keeps a version for each, shown as Desktop apps
Errors: a service can be set to keep message text
Alerts: email and text go to more than one address
Alerts: offer the digest for an issue that keeps being snoozed
API: keys and people for a token with the admin scope
Services: stop and start watching, edit checks, hold a version, and start a stopped one again
API: issue notes and bulk actions, one machine, versions, proposals, rules and routing
Libraries: Swift, and types for TypeScript
Libraries: shell
Libraries: Java, PHP and PowerShell
Libraries: JavaScript, Go, Elixir and Rust
Logs: archive months older than a year to a folder, and load one back
Server: packaging, an outside heartbeat, and a row for Dokkit itself
Program: pin the server's certificate at enrol
Libraries: Python and .NET, one file each, and hosts they report become seen machines
Alerts: rules that send one kind of issue somewhere else
Alerts: email, text and a daily digest
Numbers: metrics, machine vitals, stats documents, threshold and expiry checks
Versions: which version of each service is on which machine
Errors: accept reports from Sentry's open-source SDKs
Errors: reports in Dokkit's format, grouped, with a page, the API and the MCP
Deploys: a version change is recorded, noticed by the program or told by CI
Beats: an app says it is alive, and going quiet opens an issue
Found: a scan is proposed, and what is watched from it is checked by its machine
Tasks: offered by a dokkit.toml, accepted by the owner, run by the machine
Program: watch in the background, and start at sign-in
Program: scan, and tasks run locally
Program: run as a Windows service
Program: log file reading, init and status
Tests: drop unused imports from the data case, pipe the report answers
Cut what is not needed: one stylesheet, no telemetry or cluster deps, shared helpers
Remove what is no longer needed: the earlier galleries, the interview board, the logo images
Tidy the repo: earlier explorations in one folder, a README that says where things stand
Server: the MCP
Server: the read and act API for user tokens
Fix the Settings token test: match the whole token, not the hint in the key list
Server: Settings, with people, keys, tokens and the theme
dokkit.toml: declared checks, run by dokkit watch
Machines enrol, say they are alive, and are noticed when they stop
Server: log lines in, a Logs page, and each service's latest lines
The dokkit program: run, ping and doctor
Server: snooze, bring back and mark as seen
Server: Everything, Jobs and service pages; jobs are added in the interface
Server: alerts. An issue pages, pushes or calls a webhook once, and resolves what it raised
Server: sign-in, and a setup code that lets the first visitor claim a new server
Server: first slice. Job pings and reports in, issues out, a live Inbox
Design so far: decisions, the interface mock, and the explorations behind it