diff --git a/coworker/teams/journal.py b/coworker/teams/journal.py index c20260f6..be2ecdec 100644 --- a/coworker/teams/journal.py +++ b/coworker/teams/journal.py @@ -123,9 +123,8 @@ class JournalStore: raise BoardError(f"unknown entry kind: {kind} (use one of {JOURNAL_KINDS})") if len(body) > JOURNAL_BODY_LIMIT: raise BoardError( - f"entry body over {JOURNAL_BODY_LIMIT} chars — store the full" - " payload as an artifact and journal an excerpt with a" - " sha256-qualified ref" + f"entry body over {JOURNAL_BODY_LIMIT} chars — save the full" + " capture to a file and journal an excerpt that references it" ) with self._lock: exists = self._case_exists(case) diff --git a/coworker/teams/model.py b/coworker/teams/model.py index 37c057c4..5de6ba0a 100644 --- a/coworker/teams/model.py +++ b/coworker/teams/model.py @@ -64,11 +64,11 @@ LINK_KINDS = ("parent", "blocks") # link(src, "parent", dst): dst is src's pare # `note` is any observation — the journal is not only for investigations. `raw` is # a capture (log excerpt, command output); reads skip raw unless asked, and large -# payloads belong in the artifact store with a sha256-qualified ref on the entry. +# payloads belong in a file the entry references. JOURNAL_KINDS = ("finding", "evidence", "decision", "note", "raw") # An entry body is an excerpt/summary, never a blob: oversized payloads make every -# chain-verify and unfiltered read drag. Full captures go to the artifact store. +# read (and replay) drag. Full captures live as files the entry points at. JOURNAL_BODY_LIMIT = 16_000 diff --git a/coworker/teams/tools.py b/coworker/teams/tools.py index 60fcccae..50deef56 100644 --- a/coworker/teams/tools.py +++ b/coworker/teams/tools.py @@ -166,11 +166,11 @@ def journal_tools( refs: Optional[list] = None, ) -> dict: """Append an entry to a journal case as you work: kind is finding, - evidence, decision, note (any observation), or raw (a capture — put an - excerpt here and store the full payload as an artifact, referenced with - a sha256-qualified ref). `entities` are the concrete things it is about - (file paths, resource names, CVE ids) — they power later recall; - `refs` are pointers (file:line, commit, url, artifact).""" + evidence, decision, note (any observation), or raw (a capture like a log + excerpt — for large captures, save the full output to a file and journal + an excerpt that references it). `entities` are the concrete things it is + about (file paths, resource names, CVE ids) — they power later recall; + `refs` are pointers (file:line, commit, url).""" return _call( journal.append, actor, diff --git a/tests/test_team_journal.py b/tests/test_team_journal.py index e9924902..065ad0c7 100644 --- a/tests/test_team_journal.py +++ b/tests/test_team_journal.py @@ -130,15 +130,15 @@ def test_raw_captures_are_opt_in_on_read(journal): journal.append(LEAD, "ops", "deploy finished 14:01", kind="note") journal.append( LEAD, "ops", "nginx 5xx burst 14:02-14:04 (2,400 lines)", kind="raw", - refs=["artifact:sha256:ab12...:nginx-error.log"], + refs=["logs/nginx-error-1402.log"], ) assert len(journal.read(LEAD, "ops")) == 1 # raw skipped by default assert len(journal.read(LEAD, "ops", include_raw=True)) == 2 - assert journal.read(LEAD, "ops", kind="raw")[0]["refs"][0].startswith("artifact:") + assert journal.read(LEAD, "ops", kind="raw")[0]["refs"] == ["logs/nginx-error-1402.log"] -def test_oversized_bodies_are_refused_with_the_artifact_pattern(journal): - with pytest.raises(BoardError, match="artifact"): +def test_oversized_bodies_are_refused_with_the_excerpt_pattern(journal): + with pytest.raises(BoardError, match="excerpt"): journal.append(LEAD, "ops", "x" * (JOURNAL_BODY_LIMIT + 1), kind="raw")