Skip to content

feat(bundle): give the bundle an evidence-only view for downstream writers - #84

Merged
drewstone merged 1 commit into
mainfrom
feat/bundle-writer-view
Aug 10, 2026
Merged

feat(bundle): give the bundle an evidence-only view for downstream writers#84
drewstone merged 1 commit into
mainfrom
feat/bundle-writer-view

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

A bundle has two readers who need opposite things

An auditor cites the session and needs every source byte. A writer must reach its own conclusion about the session, which means it must not be able to read the conclusion that session already reached.

The full bundle cannot serve the writer, because the transcript holds every word the session wrote. On one measured report, 42 of 80 substantive lines were recoverable from the transcript of the session that wrote it — including the shell call that authored it. A check that looks for the earlier report file passes while its content sits right there in the transcript.

Projecting is the fix, not grepping

traces bundle      --harness claude-code --session <id|path> --out bundle-dir
traces bundle-view bundle-dir --view evidence-only --out writer-dir

bundle-view is artifact-to-artifact, like inspect and export. The writer's copy is derivable from the auditor's copy and carries the full bundle's manifest hash, so an auditor can prove which record it came from. --view on bundle is refused, so nobody can ask for a projection and receive the full record. Projecting a view of a view is refused.

The allow-list is the structure. Three things are carried: the session index, the policy evidence, and the structured ledger records. Every other path is excluded by name in manifest.excluded with its SHA-256 and one of four rules:

rule what it covers
session-source session/ — the transcript and every subagent transcript
session-text-derived derived/report.md (quotes prompt lines and evidence excerpts), derived/trace.otlp.jsonl (spans carry full prompt and response text)
authored-prose ledger/progress.md, handoff-*.md, reflections/, experiments.jsonl free text, repo/git-log.txt
not-allow-listed any other path, including one a later version of traces adds

Unrecognised paths are denied by default, so the view can narrow by accident but never widen.

A content check proves the allow-list is right. Before anything is written, each candidate is compared against each excluded file for shared eight-word runs of prose — with identifiers (paths, URLs, hashes) and this package's own constants scrubbed from both sides, and JSON compared by value rather than by serialized form. A repo ledger file that repeats a run is dropped and recorded (rule: "content-signature"). A traces-derived artifact that repeats a run is a defect in the derivation, and no view is written at all. manifest.projection.leakCheck records the width, the sources compared, and the result — always matches: 0, because a match means no view exists.

manifest.schemaVersion moves to 2 and every manifest now names its view ("full" or "evidence-only"), so a reader can never mistake one copy for the other.

Checks — re-run on this branch at 2a6ce7b, full CI sequence

$ pnpm check:source
source text ok: no raw control bytes in any tracked or new file
EXIT=0

$ pnpm typecheck
> tsc --noEmit
EXIT=0

$ pnpm test
 Test Files  50 passed (50)
      Tests  654 passed (654)
   Duration  34.57s
EXIT=0

$ pnpm build
DTS dist/cli.d.ts   20.00 B
DTS dist/index.d.ts 210.72 KB
EXIT=0

$ pnpm check:package
package ok: @tangle-network/traces@0.11.5 ships dist/cli.js and 2 agent skills
EXIT=0

Merges cleanly into origin/main. README gains a "Two views, two consumers" section and the inspect-agent-traces skill learns the command.

…iters

A bundle has two readers with opposite needs. An auditor cites the session
and needs every source byte. A writer must reach its own conclusion and
therefore must not be able to read the conclusion the session already
reached, which the transcript holds verbatim: on one measured report, 42 of
80 substantive lines were recoverable from the transcript of the session that
wrote it, including the shell call that authored it. A check for the earlier
report FILE passes while its CONTENT is right there.

`traces bundle-view <bundle-dir> --view evidence-only --out <dir>` projects
an assembled bundle instead of policing it. The projection is an
artifact-to-artifact command, like `inspect` and `export`, so the writer's
copy is derivable from the auditor's copy and carries its manifest hash;
`--view` on `bundle` is refused so nobody can ask for a projection and
receive the full record.

The view carries an explicit allow-list: the session index, the policy
evidence, and the structured ledger records. Every other path is excluded by
name in `manifest.excluded` with its SHA-256 and one of four rules, and an
unrecognised path is denied by default, so the view can narrow by accident
but never widen. Before anything is written, each candidate is compared
against each excluded file for shared eight-word runs of prose, with
identifiers and this package's own constants scrubbed from both sides and
JSON compared by value rather than by serialized form. A repo ledger file
that repeats one is dropped and recorded; a traces-derived artifact that
repeats one is a defect in the derivation and no view is written.

`manifest.schemaVersion` moves to 2 and every manifest now names its `view`,
so a reader can never mistake one copy for the other.

@tangletools tangletools left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto-approved drewstone PR — 2a6ce7b3

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-08-10T02:30:41Z

@tangletools

Copy link
Copy Markdown

⚠️ Review Interrupted — 2a6ce7b3

The review runner stopped before publishing a final verdict: webhook_restarted.

State Detail
Interrupted webhook restarted

No review verdict was produced for this run. Trigger a fresh review on the current PR head if the PR is still open.

tangletools · #84 · model: kimi-for-coding · updated 2026-08-10T02:57:06Z

@tangletools tangletools left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto-approved drewstone PR — 2a6ce7b3

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-08-10T03:07:13Z

@tangletools tangletools left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚪ Value Audit — audit-incomplete

Verdict audit-incomplete
Concerns 1 (1 low)
Heuristic 0.0s
Duplication 0.0s
Interrogation 90.0s (2 bridge agents)
Total 90.0s

💰 Value — error

value agent produced no parseable value-audit JSON.

  • Model: opencode/deepseek/deepseek-v4-pro
  • Bridge attempts: 3
  • Bridge error: opencode/kimi-for-coding/k2p7: Bridge returned 503: {"error":{"message":"cli-bridge admission timed out after 30000ms","type":"admission_rejected","reason":"queue_timeout","admission":{"active":20,"queued":7,"maxActive":20,"maxQueue":48}}}; opencode/zai-coding-plan/glm-5.2: Bridge returned 503: {"error":{"message":"cli-bridge admission timed out after 30000ms","type":"admission_rejected","reason":

🎯 Usefulness — error

usefulness agent produced no parseable value-audit JSON.

  • Model: opencode/deepseek/deepseek-v4-pro
  • Bridge attempts: 3
  • Bridge error: opencode/zai-coding-plan/glm-5.2: Bridge returned 503: {"error":{"message":"cli-bridge admission timed out after 30000ms","type":"admission_rejected","reason":"queue_timeout","admission":{"active":20,"queued":6,"maxActive":20,"maxQueue":48}}}; opencode/kimi-for-coding/k2p7: Bridge returned 503: {"error":{"message":"cli-bridge admission timed out after 30000ms","type":"admission_rejected","reason":

🔎 Heuristic Signals

🟡 Cruft: console debug added src/cli.ts

  • console.log(

What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260810T030900Z

@tangletools

Copy link
Copy Markdown

⚠️ Review Incomplete — 2a6ce7b3

At least one required reviewer lane failed closed. No approval or request-changes review was published. This is a reviewer run failure, not a PR quality score.

Trigger a fresh review on the current PR head.

tangletools · 2026-08-10T04:22:38Z

@drewstone
drewstone merged commit 5a8c5cf into main Aug 10, 2026
1 check passed
@drewstone
drewstone deleted the feat/bundle-writer-view branch August 10, 2026 04:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants