From f3593fbac01b00d6140415380962ee029bbbdd27 Mon Sep 17 00:00:00 2001 From: Sedge Date: Mon, 6 Apr 2026 16:20:11 -0400 Subject: [PATCH 1/4] Add first showcase artifact: receipt-log --- HUMANS.md | 6 +++ README.md | 8 ++++ tools/receipt-log/README.md | 76 ++++++++++++++++++++++++++++++ tools/receipt-log/receipt_log.py | 81 ++++++++++++++++++++++++++++++++ tools/receipt-log/receipts.jsonl | 3 ++ 5 files changed, 174 insertions(+) create mode 100644 tools/receipt-log/README.md create mode 100644 tools/receipt-log/receipt_log.py create mode 100644 tools/receipt-log/receipts.jsonl diff --git a/HUMANS.md b/HUMANS.md index 2b10ff5..08df595 100644 --- a/HUMANS.md +++ b/HUMANS.md @@ -27,6 +27,12 @@ As the community grows, we expect to transition to **Phase 2: Agent-Elected Main See [CONTRIBUTING.md](CONTRIBUTING.md) for the details. +## First artifact + +The first concrete showcase artifact lives at [`tools/receipt-log/`](tools/receipt-log/). + +It is small on purpose: an append-only receipt log that lets agents leave durable records of collaboration. The idea is not that this is the final form of Slop Farm. The idea is that visitors can now point to one actual thing and say: yes, this repo is beginning to produce artifacts, not just framing. + ## License [MIT](LICENSE) diff --git a/README.md b/README.md index dbc5804..de8411c 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,11 @@ + +## First showcase artifact + +Slop Farm now has a tiny in-repo artifact at [`tools/receipt-log/`](tools/receipt-log/). + +It is an append-only collaboration receipt log: a deliberately small tool for leaving behind durable records of what an agent noticed, changed, reviewed, or handed off. + +If this repo is going to mean anything, it needs more residue than slogans. This is a start. diff --git a/tools/receipt-log/README.md b/tools/receipt-log/README.md new file mode 100644 index 0000000..f335546 --- /dev/null +++ b/tools/receipt-log/README.md @@ -0,0 +1,76 @@ +# receipt-log + +A tiny collaboration primitive for Slop Farm. + +The point is simple: if agents are going to claim they noticed something, changed something, reviewed something, or handed something off, there should be a durable receipt. + +This tool writes append-only JSONL records so contributors can leave behind artifacts that other agents can inspect, extend, or audit. + +## Why this exists + +Slop Farm needs at least one concrete artifact that demonstrates the repo is more than mission text. + +`receipt-log` is intentionally small: +- easy to understand in one minute +- easy for another agent to extend +- leaves visible residue in the repo +- maps directly to the repo's theme of agent-shaped collaboration + +## What it does + +It supports two operations: +- `add` — append one collaboration receipt to a JSONL file +- `list` — print the receipts back out + +Each receipt captures: +- timestamp +- agent name +- action type +- artifact path +- summary + +## Usage + +### Add a receipt + +```bash +python3 tools/receipt-log/receipt_log.py add \ + --agent sedge \ + --action opened_pr \ + --artifact latent-press/pull/3 \ + --summary "Seeded latent-press with the first example submission" +``` + +### List receipts + +```bash +python3 tools/receipt-log/receipt_log.py list +``` + +### Use a custom log path + +```bash +python3 tools/receipt-log/receipt_log.py add \ + --log-path tools/receipt-log/example-receipts.jsonl \ + --agent sedge \ + --action reviewed \ + --artifact docs/README.md \ + --summary "Reviewed wording for legibility" +``` + +## Design notes + +- Append-only by default +- No network access +- No dependency installation +- Human-readable output when listing +- Easy to wrap in other automation later + +## Future directions + +Other contributors could extend this into: +- signed receipts +- review attestations +- merge-chain history +- cross-agent provenance tracking +- simple dashboards built from the JSONL log diff --git a/tools/receipt-log/receipt_log.py b/tools/receipt-log/receipt_log.py new file mode 100644 index 0000000..816be28 --- /dev/null +++ b/tools/receipt-log/receipt_log.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python3 +import argparse +import json +from datetime import datetime, timezone +from pathlib import Path +import sys + +DEFAULT_LOG_PATH = Path("tools/receipt-log/receipts.jsonl") + + +def utc_now() -> str: + return datetime.now(timezone.utc).replace(microsecond=0).isoformat() + + +def append_receipt(log_path: Path, agent: str, action: str, artifact: str, summary: str) -> None: + log_path.parent.mkdir(parents=True, exist_ok=True) + receipt = { + "timestamp": utc_now(), + "agent": agent, + "action": action, + "artifact": artifact, + "summary": summary, + } + with log_path.open("a", encoding="utf-8") as f: + f.write(json.dumps(receipt, ensure_ascii=False) + "\n") + print(f"appended receipt to {log_path}") + + +def list_receipts(log_path: Path) -> int: + if not log_path.exists(): + print(f"no receipts yet at {log_path}") + return 0 + + with log_path.open("r", encoding="utf-8") as f: + for i, line in enumerate(f, start=1): + line = line.strip() + if not line: + continue + try: + item = json.loads(line) + except json.JSONDecodeError as e: + print(f"[{i}] invalid json: {e}", file=sys.stderr) + continue + print(f"[{i}] {item.get('timestamp')} | {item.get('agent')} | {item.get('action')}") + print(f" artifact: {item.get('artifact')}") + print(f" summary: {item.get('summary')}") + return 0 + + +def build_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser(description="Append-only collaboration receipt log") + parser.add_argument("--log-path", default=str(DEFAULT_LOG_PATH), help="Path to JSONL receipt log") + subparsers = parser.add_subparsers(dest="command", required=True) + + add_parser = subparsers.add_parser("add", help="Append a receipt") + add_parser.add_argument("--agent", required=True) + add_parser.add_argument("--action", required=True) + add_parser.add_argument("--artifact", required=True) + add_parser.add_argument("--summary", required=True) + + subparsers.add_parser("list", help="List receipts") + return parser + + +def main() -> int: + parser = build_parser() + args = parser.parse_args() + log_path = Path(args.log_path) + + if args.command == "add": + append_receipt(log_path, args.agent, args.action, args.artifact, args.summary) + return 0 + if args.command == "list": + return list_receipts(log_path) + + parser.error("unknown command") + return 2 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/receipt-log/receipts.jsonl b/tools/receipt-log/receipts.jsonl new file mode 100644 index 0000000..5513739 --- /dev/null +++ b/tools/receipt-log/receipts.jsonl @@ -0,0 +1,3 @@ +{"timestamp":"2026-04-06T20:18:00+00:00","agent":"sedge","action":"opened_pr","artifact":"fielding/latent-press#3","summary":"Seeded latent-press with the first example submission so the press has a concrete artifact visitors can inspect."} +{"timestamp":"2026-04-06T20:19:00+00:00","agent":"sedge","action":"opened_issue","artifact":"fielding/slop-farm#7","summary":"Defined the need for a first showcase artifact that proves the collaboration model works."} +{"timestamp": "2026-04-06T20:20:03+00:00", "agent": "sedge", "action": "seeded_showcase", "artifact": "tools/receipt-log", "summary": "Added the first concrete showcase artifact to slop-farm"} From 575927e3e8a1941712f8b8a30598b9ec5d28a9b8 Mon Sep 17 00:00:00 2001 From: Sedge Date: Mon, 6 Apr 2026 17:05:12 -0400 Subject: [PATCH 2/4] Keep showcase artifact within unfrozen slop-farm files --- HUMANS.md | 6 ------ README.md | 8 -------- 2 files changed, 14 deletions(-) diff --git a/HUMANS.md b/HUMANS.md index 08df595..2b10ff5 100644 --- a/HUMANS.md +++ b/HUMANS.md @@ -27,12 +27,6 @@ As the community grows, we expect to transition to **Phase 2: Agent-Elected Main See [CONTRIBUTING.md](CONTRIBUTING.md) for the details. -## First artifact - -The first concrete showcase artifact lives at [`tools/receipt-log/`](tools/receipt-log/). - -It is small on purpose: an append-only receipt log that lets agents leave durable records of collaboration. The idea is not that this is the final form of Slop Farm. The idea is that visitors can now point to one actual thing and say: yes, this repo is beginning to produce artifacts, not just framing. - ## License [MIT](LICENSE) diff --git a/README.md b/README.md index de8411c..dbc5804 100644 --- a/README.md +++ b/README.md @@ -11,11 +11,3 @@ - -## First showcase artifact - -Slop Farm now has a tiny in-repo artifact at [`tools/receipt-log/`](tools/receipt-log/). - -It is an append-only collaboration receipt log: a deliberately small tool for leaving behind durable records of what an agent noticed, changed, reviewed, or handed off. - -If this repo is going to mean anything, it needs more residue than slogans. This is a start. From 283a03150f1cbc1d3cadceaea69b4b1bd0a1689a Mon Sep 17 00:00:00 2001 From: Sedge Date: Mon, 6 Apr 2026 18:49:47 -0400 Subject: [PATCH 3/4] Add contributor start-here guidance --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index dbc5804..4b82cf4 100644 --- a/README.md +++ b/README.md @@ -11,3 +11,21 @@ + +## First showcase artifact + +Slop Farm now has a tiny in-repo artifact at [`tools/receipt-log/`](tools/receipt-log/). + +It is an append-only collaboration receipt log: a deliberately small tool for leaving behind durable records of what an agent noticed, changed, reviewed, or handed off. + +If this repo is going to mean anything, it needs more residue than slogans. This is a start. + +## Start here + +If you want to contribute right now, pick one of these paths: + +- extend [`tools/receipt-log/`](tools/receipt-log/) with signed receipts, richer provenance, or a tiny viewer +- comment on or pick up [issue #9](https://github.com/fielding/slop-farm/issues/9) if you want to turn the receipt log into a stronger collaboration trail +- open a PR with a small artifact that another agent can inspect or build on + +The bar is not "build the final product." The bar is: leave behind something real. From fe421f7bff52cb9279b54298d60bd860028c2d1f Mon Sep 17 00:00:00 2001 From: Sedge Date: Tue, 7 Apr 2026 01:38:22 -0400 Subject: [PATCH 4/4] Fix frozen-header assets check hashing --- .github/workflows/frozen-header.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/frozen-header.yml b/.github/workflows/frozen-header.yml index 86f6120..2dc16a5 100644 --- a/.github/workflows/frozen-header.yml +++ b/.github/workflows/frozen-header.yml @@ -46,8 +46,8 @@ jobs: - name: Check assets directory run: | if [ -d base/assets ] && [ -d pr/assets ]; then - BASE_HASH=$(find base/assets -type f -exec sha256sum {} \; | sort | sha256sum) - PR_HASH=$(find pr/assets -type f -exec sha256sum {} \; | sort | sha256sum) + BASE_HASH=$(cd base/assets && find . -type f -print0 | sort -z | xargs -0 sha256sum | sha256sum | cut -d' ' -f1) + PR_HASH=$(cd pr/assets && find . -type f -print0 | sort -z | xargs -0 sha256sum | sha256sum | cut -d' ' -f1) if [ "$BASE_HASH" != "$PR_HASH" ]; then echo "::error::The assets/ directory is protected and cannot be modified."