feat(PROV-1): deterministic Source Ledger — renderer + idempotent publication #308

Merged
conductor merged 2 commits from prov1-source-ledger into master 2026-09-09 19:03:58 +01:00
Owner

PROV-1: deterministic Source Ledger (closes #282)

Branch prov1-source-ledger, commit 2da0afb. Deliberately boring: accepted OUTWARD artifact + receipts + persisted metadata → pure deterministic render → fixed Markdown template → idempotent Gitea comment.

Hard boundaries implemented:

  • READ impossible without a successful machine receipt (SOURCE_READ with matching URL); artifact-claimed-read without receipt downgrades to FAILED honestly
  • BLOCKED / FAILED / NOT_SELECTED appear in the ledger and back ZERO accepted claims; NOT_SELECTED (never attempted) distinct from BLOCKED (attempted, refused)
  • runner/model from persisted factual fields only, UNKNOWN if absent — never reconstructed from session memory; model+runner now persisted into the accepted artifact at the smallest authority point
  • requested_url + resolved_url both retained
  • explicit contradicts_source_ids used when present; legacy nesting labeled in render; plain-string contradictions honestly not linked
  • renderer failure raises visibly; publication failure raises visibly; neither alters research cognition or stage outcomes
  • receipt_id deterministic: hash of stage+tool+canonical_url+timestamp+event-seq
  • no trust scores — factual classification only

Real acceptance on #161 (legacy artifact, honest labels):

  • 16 records: 4 READ (machine receipts replayed from the genuine events file), 12 NOT_SELECTED backing zero claims
  • Ledger live on Gitea issue 161 (comment 3510): source URL → READ → receipt → E-claims → ledger row visually verifiable
  • runner/model UNKNOWN (legacy run — labeled, not reconstructed); legacy-nesting note rendered

Idempotency proven: publish → created (comment 3510); publish again → UPDATED same comment. No duplicates.

14 ledger tests; full suite 1152 passed; ruff clean.

Ratification limitation 5 CLOSED. Epic #284: 3/5 limitations closed (#287, #286, #282); #298 ADAPT-9 outstanding; #288 accepted limitation.

## PROV-1: deterministic Source Ledger (closes #282) Branch `prov1-source-ledger`, commit 2da0afb. Deliberately boring: accepted OUTWARD artifact + receipts + persisted metadata → pure deterministic render → fixed Markdown template → idempotent Gitea comment. **Hard boundaries implemented:** - READ impossible without a successful machine receipt (SOURCE_READ with matching URL); artifact-claimed-read without receipt downgrades to FAILED honestly - BLOCKED / FAILED / NOT_SELECTED appear in the ledger and back ZERO accepted claims; NOT_SELECTED (never attempted) distinct from BLOCKED (attempted, refused) - runner/model from persisted factual fields only, UNKNOWN if absent — never reconstructed from session memory; model+runner now persisted into the accepted artifact at the smallest authority point - requested_url + resolved_url both retained - explicit contradicts_source_ids used when present; legacy nesting labeled in render; plain-string contradictions honestly not linked - renderer failure raises visibly; publication failure raises visibly; neither alters research cognition or stage outcomes - receipt_id deterministic: hash of stage+tool+canonical_url+timestamp+event-seq - no trust scores — factual classification only **Real acceptance on #161** (legacy artifact, honest labels): - 16 records: 4 READ (machine receipts replayed from the genuine events file), 12 NOT_SELECTED backing zero claims - Ledger live on Gitea issue 161 (comment 3510): source URL → READ → receipt → E-claims → ledger row visually verifiable - runner/model UNKNOWN (legacy run — labeled, not reconstructed); legacy-nesting note rendered **Idempotency proven**: publish → created (comment 3510); publish again → UPDATED same comment. No duplicates. 14 ledger tests; full suite 1152 passed; ruff clean. **Ratification limitation 5 CLOSED. Epic #284: 3/5 limitations closed (#287, #286, #282); #298 ADAPT-9 outstanding; #288 accepted limitation.**
conductor added 1 commit 2026-09-09 18:57:20 +01:00
feat(PROV-1): deterministic Source Ledger — renderer, persisted metadata, idempotent Gitea publication (closes #282)
CI Pipeline / best-practices (push) Successful in 4s
CI Pipeline / documentation (push) Successful in 3s
Auto-label / priority-gate (pull_request) Skipped
CI Pipeline / lint (push) Failing after 28s
Auto-label / auto-label (pull_request) Successful in 2s
CI Pipeline / canary (push) Successful in 33s
CI Pipeline / type-check (push) Successful in 28s
CI Pipeline / gitea-offline (push) Successful in 16s
CI Pipeline / unit-tests (push) Successful in 57s
CI Pipeline / best-practices (pull_request) Successful in 4s
CI Pipeline / documentation (pull_request) Successful in 3s
CI Pipeline / lint (pull_request) Failing after 26s
CI Pipeline / canary (pull_request) Successful in 31s
Spec gate (headless) / spec-gate (pull_request) Successful in 6s
CI Pipeline / gitea-offline (pull_request) Successful in 16s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / type-check (pull_request) Successful in 29s
CI Pipeline / unit-tests (pull_request) Successful in 57s
CI Pipeline / required-checks (pull_request) Successful in 1s
2da0afb324
scripts/source_ledger.py — pure deterministic projection:
- build_records: accepted OUTWARD artifact + SOURCE_READ/TOOL_FAILED receipts
  → ledger records with receipt_id (deterministic hash of stage+tool+
  canonical_url+timestamp+seq), source_id, requested_url+resolved_url,
  domain, status, tool, timestamp, source_type, claim_ids,
  contradiction_ids, blocked_reason
- THE safety invariant: READ impossible without a successful machine
  receipt; artifact-claimed-read with no matching receipt downgrades to
  FAILED honestly; BLOCKED/FAILED/NOT_SELECTED back ZERO accepted claims
- NOT_SELECTED distinct from BLOCKED (never attempted ≠ attempted-refused)
- explicit contradicts_source_ids used when present; legacy nesting labeled
  in render; plain-string contradictions not linked (labeled honestly)
- render_markdown: fixed template; runner/model from persisted factual
  fields only, UNKNOWN if absent — never reconstructed

scripts/publish_source_ledger.py — idempotent Gitea publication:
- comment identified by marker containing artifact hash; same hash UPDATES,
  new hash creates; publication failure raises VISIBLY (never silently
  falsifies the ledger) and does not alter stage outcomes

research_stage_executor.py: model + runner persisted into the accepted
OUTWARD artifact (smallest authority point; PROV-1 metadata fields)

Real acceptance on #161: 16 records (4 READ with machine receipts replayed
from the genuine events file, 12 NOT_SELECTED backing zero claims), ledger
live on Gitea issue 161 (comment 3510), idempotency proven (second publish
updates same comment). Legacy artifact honestly labeled UNKNOWN for
runner/model and legacy-nesting noted in render.

14 ledger tests; full suite 1151 passed; ruff clean.
gitea-actions Bot added the bugcustodianinfrastructurememory labels 2026-09-09 18:57:29 +01:00

🤖 Headless spec gate (non-blocking, #204 first slice)

Spec-gate agent produced no text output — check runner logs.

Deterministic floors still govern the merge

This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.

🤖 **Headless spec gate (non-blocking, #204 first slice)** Spec-gate agent produced no text output — check runner logs. <details><summary>Deterministic floors still govern the merge</summary> This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.</details>
conductor added 1 commit 2026-09-09 19:01:13 +01:00
chore(ci): resync dependency lock — pyright 1.1.411 → 1.1.412 (upstream drift)
CI Pipeline / best-practices (push) Successful in 10s
CI Pipeline / documentation (push) Successful in 2s
CI Pipeline / lint (push) Successful in 38s
CI Pipeline / canary (push) Successful in 39s
CI Pipeline / type-check (push) Successful in 30s
CI Pipeline / gitea-offline (push) Successful in 15s
CI Pipeline / unit-tests (push) Successful in 1m4s
CI Pipeline / best-practices (pull_request) Successful in 3s
CI Pipeline / lint (pull_request) Successful in 36s
CI Pipeline / canary (pull_request) Successful in 30s
CI Pipeline / required-checks (push) Successful in 1s
CI Pipeline / unit-tests (pull_request) Successful in 1m7s
CI Pipeline / documentation (pull_request) Successful in 3s
Spec gate (headless) / spec-gate (pull_request) Successful in 8s
CI Pipeline / gitea-offline (pull_request) Successful in 16s
CI Pipeline / type-check (pull_request) Successful in 30s
CI Pipeline / required-checks (pull_request) Successful in 1s
Auto-version and Release / release (pull_request) Successful in 40s
e7d4c2ad9b

🤖 Headless spec gate (non-blocking, #204 first slice)

Spec-gate agent produced no text output — check runner logs.

Deterministic floors still govern the merge

This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.

🤖 **Headless spec gate (non-blocking, #204 first slice)** Spec-gate agent produced no text output — check runner logs. <details><summary>Deterministic floors still govern the merge</summary> This comment is advisory. Required checks (lint, tests, canaries, type-check, coverage, dependency lock, impact gate) remain the merge authority per docs/adversarial-review.md proportionality.</details>
conductor merged commit 2093558fc4 into master 2026-09-09 19:03:58 +01:00
Sign in to join this conversation.
No Reviewers
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: conductor/rune#308