81 lines
4.7 KiB
Markdown
81 lines
4.7 KiB
Markdown
# Ledger
|
|
|
|
Read-only counts from local `refactor` commit subjects, one Gitea issue-list
|
|
request through `scripts/gitea-api.sh`, and repo seats' Pi session logs.
|
|
No board changes, data-root writes, fleet reads, transcript output, or scheduler.
|
|
|
|
```sh
|
|
node packages/ledger/src/cli.mjs --since 2026-09-06 --until 2026-09-12
|
|
node packages/ledger/src/cli.mjs --since 2026-09-06 --until 2026-09-12 --json
|
|
node packages/ledger/src/cli.mjs --since 2026-09-06 --no-issues
|
|
node --test packages/ledger/tests/
|
|
```
|
|
|
|
Dates include both endpoints in UTC. Omitted `--until` means today in UTC.
|
|
The checkout containing this package supplies the sources, not the shell's cwd.
|
|
No install, build, service restart, or configuration change is needed.
|
|
|
|
## Counting rules
|
|
|
|
- Git uses committer timestamps and every commit reachable from local `refactor`,
|
|
including merges. It reads subjects only. A repeated `#N` in one subject counts
|
|
once. A commit naming two issues counts for both rows but once in total commits.
|
|
Untagged commits do not count. Issue numbers are literal references to
|
|
`mosaicstack/stack`, with no attempt to remap archived repositories' numbers.
|
|
This can associate historical references with unrelated same-number issues.
|
|
- Table 1 includes issues with a tagged commit or a `closed_at` in range.
|
|
Opened is `created_at`; hours open is `closed_at - created_at`, rounded to one
|
|
decimal, or `open` if not closed. It is not age as of `--until`. Reopen history
|
|
is unavailable from the issue-list response. Median hours open uses only
|
|
issues closed in range and rounds after computing the median.
|
|
- Follow-ups are `max(commits in range - 1, 0)` per issue, not a lifetime count
|
|
and not a quality assessment. Follow-ups per issue divides their sum by all
|
|
Table 1 rows, including close-only rows.
|
|
- Table 2 counts user-message entries in `.pi/state/<seat>/sessions/*.jsonl`
|
|
where `<seat>` is a real directory in `agents/`. All matching files count;
|
|
duplicated entries in copied logs are not deduplicated. No transcript content
|
|
leaves the parser. Assistant messages and logs outside repo seats do not count.
|
|
Symlink source directories are refused and symlink files are not followed.
|
|
- The first text line alone classifies a message. A bracketed addressing
|
|
preamble whose source session is `control-board` is board; any other valid
|
|
addressing preamble is agent; otherwise human. This is a format count, not
|
|
proof of who typed the message. Text blocks are joined with newlines.
|
|
The entry timestamp is used, falling back to the message timestamp.
|
|
- Seats with no in-range user messages are omitted. Issue seats come from `#N`
|
|
mentions anywhere in in-range user text, including quoted text.
|
|
- Human messages per closed issue divides Table 2's human sum by issues closed
|
|
in range. A zero denominator with human messages is `unknown`; a truly empty
|
|
report has zero totals. JSON keeps numeric values as numbers; text displays
|
|
ratios and durations with one decimal. Titles truncate to 48 characters in
|
|
text only. Missing evidence is the literal string `unknown`.
|
|
|
|
## One Gitea call and missing evidence
|
|
|
|
The client requests issues updated since the start date, all states, first page,
|
|
limit 50. This includes issues closed in range, even if later updated. Gitea caps
|
|
responses at 50; a full page fails rather than silently reporting partial totals.
|
|
Use a narrower range or `--no-issues`, not hidden pagination. A commit-linked
|
|
issue not returned by the updated-since query still has a row, with unknown
|
|
metadata. This is the cost of the brief's one-call boundary.
|
|
|
|
Exit 0 means a report was computed. Exit 1 means bad arguments or unreadable git
|
|
or session evidence. Malformed JSONL, including a partially written last line,
|
|
refuses the report; rerun after the seat finishes writing. Exit 2 means issue
|
|
credentials, API, payload, or completeness failure. The CLI never prints API
|
|
error bodies or reads authentication files itself. `--no-issues` makes no API
|
|
call, keeps commit-derived rows, and shows unknown issue metadata, closed counts,
|
|
median duration, and human-per-closed ratio. It cannot invent close-only rows.
|
|
|
|
For fixtures, a fake `gitea-api.sh` can be placed first on PATH. Otherwise the
|
|
repository scripts directory is appended to PATH for the issue request.
|
|
Tests use only temporary repositories, logs, and fake API tools, with no real
|
|
credentials or network. The helper regression stubs Node before any credential
|
|
read and checks successful GET, successful POST, and failed HTTP status.
|
|
|
|
## Acceptance
|
|
|
|
Gate D is Jason's: run the requested week, choose a number to move next week,
|
|
and write the sentence and number into `docs/plans/CURRENT.md`. Automated tests
|
|
and publication do not pass that gate. Remove the package to stop using it;
|
|
there is no persistent ledger state to migrate or restore.
|