# Evidence and provenance Keep ingestion state, source evidence, and claim assessment separate. Resolve the installed product root from the invoking skill's own location, not from the user-vault working directory: ```bash PRODUCT_ROOT=/absolute/path/to/installed/claude-obsidian CORE="$PRODUCT_ROOT/scripts/claude-obsidian.py" test -f "$CORE" ``` ## Ledgers - `.raw/.manifest.json`: legacy-compatible ingestion hashes, generated pages, address map, and last processing result. - `wiki/meta/ledgers/source-ledger.json`: stable source identities, authority, SHA-256, retrieval/freshness, review state, and linked pages. - `wiki/meta/ledgers/claim-ledger.json`: falsifiable claims, note locations, support, contradictions, confidence, risk, and review state. Do not overload one ledger with all three jobs. ## Source rules - Use SHA-256 for new source identity and delta checks. - File locators are vault-relative. Remote locators are absolute HTTPS URLs. - Source authority is one of `official`, `primary`, `secondary`, `community`, `synthetic`, or `unknown`. - Review state is `unreviewed`, `active`, `superseded`, or `rejected`. - Compute staleness from `refresh_due`; do not store a second stale flag. - Sources sharing an `independence_key` do not count as independent corroboration. - Sources that resolve to the same canonical URL origin do not count as independent merely because IPv6, IDN, Unicode, dot-segment, default-port, or percent-encoding spelling differs. Escaped reserved path/query bytes remain distinct because they can identify a different resource. ## Claim rules - Assessment is `accepted`, `provisional`, `contested`, `unsupported`, or `deprecated`. - Accepted claims need at least one fresh, active, non-synthetic source. - High-risk accepted claims need two independent sources. - Preserve contradictory evidence. Do not silently select a winner. - `unsupported` is the canonical no-data state. A grounded refusal is better than confident invention. - Never fabricate quotations, page numbers, dates, or evidence locators. ## Migration Run migration as a dry-run first: ```bash python3 "$CORE" migrate --vault VAULT \ --generated-at --operation-id migrate-reviewed python3 "$CORE" migrate --vault VAULT \ --generated-at --operation-id migrate-reviewed \ --approved-plan-sha256 --apply ``` Migration leaves `.raw/.manifest.json` byte-for-byte unchanged, creates missing ledgers, defaults unknown evidence fields honestly, and never extracts claims from legacy prose automatically. A legacy source key that resolves to a regular file remains a file source with its computed SHA-256. A valid key with no file is preserved as an unreviewed manual source with unknown authority and no verified payload hash. This unresolved record preserves the legacy identity, date, and page links; it does not prove a batch-to-file relationship. Migration never enumerates raw payloads to invent that relationship or promotes the legacy short hash to SHA-256. The reviewed migration bundle also pins each legacy locator's observed file state. Apply fails if an unresolved label appears, becomes unsafe, cannot be inspected, or if a file source changes after review.