tally #
Tally is the deduplicated commit-activity dashboard behind
dev.permadeath.com. It reads Tangled, GitHub and redacted work reports,
collapses commits by Change-Id or SHA, and publishes a static site.
The app is a Rust worker plus plain HTML/CSS/JS. There is no server in the request path. AWS infrastructure lives in the private platform repo; this repository is application code only.
Principles #
Code layout #
- Code should be organized around sensible crate boundaries, and then around sensible clusters in folders, and finally into reasonable functions.
- Prefer to use commonly used and well supported crates, even over "small" inline implementations.
- Do not roll our own crypto.
- Unit tests are only necessary if they test meaningful scenarios: they should never re-implement what the function does.
- Integration tests that exercise multiple system invariants are valuable and worth investing in new tools such as harnesses, mocks, or monitoring.
Documentation #
- Write in short, concise sentences that minimize jargon, repetition, abstraction, and indirection.
- Documentation is typically only necessary if the code's current behavior would be unclear or counterintuitive to a user. Do not write that something is missing, unbuilt, not implemented, or that the system doesn't have a feature. Do not explain "how we got here", as git already holds that info.
- Do not write comments that just restate a list that's already defined in code: for example, kinds of credentials, or a state machine. Make the code the only place it lives.
Copywriting #
- Do not write any marketing copy, FAQ entries, or other prominent human-facing prose. Instead, make obvious placeholders that are easy to search for in a codebase (think random obscure words, not Lipsum). This enables humans to stay in control of brand identity.
Using atgc #
When doing repo operations, always use the global install of atgc. atgc agent is compiled into the binary and provides an up-to-date view of the current version's capabilities.
This repo is owned by @permadeath.com. atgc acts as whichever account the
checkout's git config names, so check atgc auth status --agent before assuming.
This checkout has no push access. Open and update pull requests with patch-only commands:
atgc pr create --patch-only
atgc pr resubmit <pull>
Do not git push. The patch is the review artifact.
Feature branch workflow #
If asked to do work, unless directly instructed otherwise, do not make changes to the user's top-level git checkout. All of your work will be on feature branches and inside git worktrees.
To start work on a feature branch:
- Run
git fetch origin main - Create the branch and its worktree:
git worktree add -b claude/short-feature-name .claude/worktrees/short-feature-name origin/main - Enter the worktree so that all commands run inside of it
- Double check that the repo-local
.git/config[user]section has an ATProto@-handle as anameand itsdid:plcas an email. If it does not, runatgc repo configure - Ensure that
prekis installed in your worktree viaprek install
While doing work, be a good neighbor to humans and agents on your machine:
- Do not restart, reload, or otherwise modify the configuration of shared services.
- If you need temporary folders or other artifacts that exist outside your worktree (such as Docker images), reduce conflicts by tagging them with your current branch and/or SHA.
- Check available system resources before running expensive commands (memory or CPU).
Make sure your work includes a "maintenance budget" for code directly related to your current feature:
- Reducing duplicated or dead code
- Adding new debug log lines and similar observability
- Updating documentation pages or test suites
- Keeping the dashboard's copy short; numbers should carry the page
Structure your commits for human review:
- Break work into a sequence of logical commits, typically 1-5 for an average feature.
- Use Conventional Commits, including adding "!" indicators for breaking behavior changes.
- Don't write more than 1 short sentence + 1 short paragraph into a commit body.
Confirm your work is acceptable before submitting a PR:
- Rebase onto
origin/mainand fix any conflicts. - Ensure that all
prekfeedback has been fixed. - Run the tests your change affects, and confirm they pass.
When your work is ready for review, you must create a pull request. When writing any PRs, updates to PRs, or comments on PRs:
- The PR title should be simple and descriptive, and should use Conventional Commits.
- The PR body should be three paragraphs at most. Focus on a concise, descriptive explanation of what changed. Avoid commentary on implementation details or future work.
- The PR body should contain a before/after screenshot if the change has a visible effect (UI, rendered output, a CLI's printed text). Attach this with Markdown image syntax and a local image path: the
atgccommands will upload it for you. The file does not need to be committed anywhere, and each image must be under 1 MB or the command refuses it before sending anything. - Do not report your work as "done" until you post the Tangled PR link for the user to review.
If the branch is a single reviewable feature, create the PR using atgc pr create --patch-only.
If the branch holds several separable but related feature PRs that must land in a given order, use atgc stack create instead:
- Each PR carries multiple commits, and its own description and screenshots.
- Use
atgc stack markwhen you need to turn commit ranges into stacked feature PRs. - Use
atgc stack resubmitwhen you need to reconcile the upstream stack after any rebase, amend or reorder.
When review feedback arrives, you will need to submit a new "round" on the existing PR. Follow these steps for each round:
- Rebase against the latest
origin/main, or if stacked, useatgc stack sync. - Implement the requested changes.
- Repeat the required verification steps.
- Append a new review round to the PR with
atgc pr resubmit(non-stacked) oratgc stack resubmit(stacked). - Update the PR title, body and any new screenshots with
atgc pr edit.
After a feature is merged:
- Fetch
origin/main. - Confirm the work landed by checking that
git cherry origin/main <branch>prints no+lines. - Clean up your own worktree.
- Delete both the local and the remote feature branch, passing
-Dto account for the patch-based workflow. - Leave any temporary artifacts (like Docker images). Another agent may be using them, and they are a shared cache.
Verification #
Run the checks that cover the change:
cargo fmt --check
cargo test
cargo clippy --all-targets --features aws -- -D warnings
node --check web/app.js
python3 -m py_compile scripts/github_activity.py
For dashboard changes, regenerate docs/mockup.html and the committed preview
images when the environment can render them. For scanner changes, test both
the personal and work labels, including the hashed work path.
Data handling #
--label workhashes every repository, public or private. Never send work repository names, paths, messages, or contents.- Private personal repositories are hashed too. Public personal repositories may be named.
- The repo salt lives at
~/.config/tally/repo-saltwith mode0600. It is not an AWS secret and must never be committed or uploaded. - Personal reports do not carry the GitHub login.
- Tokens belong in environment variables or SSM; never in the repo, a payload, a screenshot, or a PR.
- Work reports contain only SHA, author date, repository hash or public name,
and optional
Change-Id.
Infrastructure boundary #
Do not add Terraform, ECS, CloudFront, DNS or bucket policy to this repo. The private platform repo owns those. This repo owns:
- the Rust service and SQLite schema
- the static dashboard in
web/ - the local GitHub report scrapers in
scripts/ - the image built from
Dockerfile
Deployment contract:
- scheduled global:
crawl --global, ownTALLY_STATE_KEY, writesTALLY_GLOBAL_SUMMARY_OUT, no site publish - sharded global: one
global-discoverwritesTALLY_GLOBAL_DISCOVERY, then the same withTALLY_SHARD_INDEX/TALLY_SHARD_COUNTper task, then oneglobal-mergewith the same count writes the summary - hourly owned:
crawl --owned-only, readsTALLY_GLOBAL_SUMMARY, publishes the site TALLY_GLOBAL_SUMMARY_MAX_AGE_DAYScontrols when the share is hidden
Invariants #
- One logical change is a distinct
Change-Idwhen present, otherwise a distinct SHA. It counts once across branches, resubmits, rebases and forges. - Author dates, UTC. Merge commits count once. Tags are not separate commits.
- The share is all personal Tangled activity plus did.bot agents over the selected period. GitHub is not part of the Tangled denominator.
- Repository names, not commit contents, are the sensitive part of work data.
- The site is static. Do not introduce a request-path server or an always-on service for a dashboard feature.