docs(hashing): add hash computation site reference document (ITL-529)#238
Conversation
…ation hash (ITL-529)
…L-529) Add Part 3 covering site 11 (DataFunction URI / output_schema_hash), sites 12+13 (PipelineJob run_id and snapshot_hash), and site 14 (datagram UUID). Also add the if __name__ == "__main__" guard and fix the SideEffectPod callback signature to accept **kwargs for data columns. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… Run Identity (ITL-529)
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
…ew (ITL-529) - Fix site 9 preimage: remove NODE_CONTENT_HASH_COL (removed in ITL-533); fix INPUT_DATA_HASH_COL type pa.large_string → pa.large_binary - Fix site 9/10 uniqueness guarantee: pod-version scoping is via table path (uri + pipeline_hash()), not preimage — consistent with sites 7–8 - Fix §4 intro: remove stale NODE_CONTENT_HASH_COL narrative - Fix FunctionPod identity_structure(): bare data_function (not 1-tuple) when no ctx - Fix RootSource identity_structure(): actual return shape (class_name, schemas, source_id) - Fix ArrowTableStream fallbacks: document actual 3-tuple and schema-pair cases - Fix §1b FunctionPod note: ctx-aware and plain pods have different uri and DB table paths; shared pipeline_hash value does not imply shared table path - Fix site 6 algorithm: n_char is system_tag_n_char, not schema_n_char - Fix site 7 known exclusions: table path scoped by uri + pipeline_hash(), not pipeline_hash() alone
…sites-document-inputs-algorithm
There was a problem hiding this comment.
Pull request overview
Adds a developer-facing hashing reference for orcapod-python, plus a reproducible script to print concrete hash values used in the documentation, and wires the page into the MkDocs nav.
Changes:
- Add
docs/reference/hashing.md, cataloguing 14 hash computation sites and including a worked example with concrete values. - Add
superpowers/scripts/hash_audit_example.py, a runnable script that constructs a deterministic pipeline and prints the relevant hash outputs. - Update documentation scaffolding (MkDocs nav + supporting superpowers artifacts / ignore rules).
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| superpowers/specs/2026-07-21-itl-529-hash-audit-design.md | Design spec for the hashing reference doc and audit script |
| superpowers/scripts/hash_audit_example.py | Script to generate concrete hash values for documentation |
| mkdocs.yml | Adds the new reference page to the MkDocs navigation |
| docs/reference/hashing.md | New hashing reference document (14 sites + worked example) |
| docs/metamorphic/plans/2026-07-21-itl-529-hash-audit-reference.md | Implementation plan for generating the doc + script |
| .gitignore | Adjusts ignore rules to allow committing superpowers scripts |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Side-effect pods (and `FunctionPod` instances with a `ctx_arg_name`) use a parallel but | ||
| distinct record key scheme. The row-level preimage structure mirrors §3; pod-version | ||
| scoping is handled at the delivery log's table-path level via `pipeline_hash()` and `uri`, | ||
| not at the preimage level — consistent with how `FunctionJobNode` scopes function cache | ||
| entries in §3. |
There was a problem hiding this comment.
Fixed. This was a genuine code oversight from ITL-533: _build_invocation_context() in function_pod.py still included NODE_CONTENT_HASH_COL (as pa.large_string()) and used to_string()/large_string() for INPUT_DATA_HASH_COL — inconsistent with FunctionJobNode and SideEffectPod which were both updated by ITL-533.
The fix (commit bdae918):
- Replaced the manual preimage construction in
_build_invocation_context()with the shared_build_record_id_preimage()helper fromfunction_node.py(deferred import to avoid circular dependency), then appends only_SIDE_EFFECT_RECOMPUTATION_INDEX_COL. This removesNODE_CONTENT_HASH_COLand switchesINPUT_DATA_HASH_COLtoto_prefixed_digest()/large_binary()— matchingSideEffectPodexactly. - Updated
hashing.md§4 / site 10 to reflect that both paths now share the same preimage structure. - Added a regression test in
test_node_content_hash_redundancy.pyassertingNODE_CONTENT_HASH_COLis absent andINPUT_DATA_HASH_COLislarge_binaryin the invocation context preimage.
All 4565 tests pass.
|
|
||
| **Format:** Prose explaining the two-component structure, then per-site template. | ||
|
|
||
| **Opening prose:** Side-effect pods (and `FunctionPod` instances with a `ctx_arg_name`) use a parallel but distinct record key scheme. The key difference from Section 3 is the inclusion of `NODE_CONTENT_HASH_COL` — so that changing the pod's implementation invalidates prior delivery records, even for the same input. The `invocation_hash` string is composed from two `ContentHash` components and exposed to the pod function as an idempotency key. |
There was a problem hiding this comment.
This is a historical planning spec artifact (superpowers/specs/), not a shipped library document. The authoritative documentation is docs/reference/hashing.md, which has been corrected. The spec pre-dates ITL-533 removing NODE_CONTENT_HASH_COL from the preimage and does not need updating.
| | Inputs | System tags + `INPUT_DATA_HASH_COL` (as `pa.large_string()`) + `NODE_CONTENT_HASH_COL` (pod `content_hash().to_string()`, as `pa.large_string()`) + `_SIDE_EFFECT_RECOMPUTATION_INDEX_COL` (fixed `0`, `pa.int32`) | | ||
| | Algorithm | `StarfixArrowHasher.hash_table(preimage)` → `.to_prefixed_digest()` | | ||
| | Output format | `ContentHash` (internally); `.to_prefixed_digest()` → `bytes` when stored in the delivery log | | ||
| | Uniqueness guarantee | Unique per `(tag lineage, input_data content, pod version)`; recomputation index is always `0` — side-effect pods do not version recomputations | | ||
| | Known exclusions | Unlike sites 7–8, this includes `NODE_CONTENT_HASH_COL` — a deliberate difference ensuring that changing the pod version invalidates the delivery record even for unchanged inputs | |
There was a problem hiding this comment.
Same as the previous comment — this is a historical planning spec artifact that pre-dates ITL-533. The authoritative reference is docs/reference/hashing.md, which correctly documents both FunctionPod._build_invocation_context() and SideEffectPod using to_prefixed_digest()/large_binary() with no NODE_CONTENT_HASH_COL in the preimage (after the fix in commit bdae918).
| def _log_fn(data, ctx: InvocationContext) -> None: # noqa: ANN001 | ||
| captured_ctx.append(ctx) |
There was a problem hiding this comment.
This is a historical implementation plan artifact (docs/metamorphic/plans/). The actual script (superpowers/scripts/hash_audit_example.py) was already written with the correct signature: def _log_fn(ctx: InvocationContext, **kwargs) -> None: — matching how SideEffectPod calls the function with **{ctx_arg_name: ctx, **data_dict}.
…n_context preimage ITL-533 removed NODE_CONTENT_HASH_COL from the record_id preimage in FunctionJobNode and SideEffectPod but missed _build_invocation_context() in function_pod.py. This commit aligns the ctx-aware FunctionPod path with the same preimage structure used everywhere else: system_tags + INPUT_DATA_HASH_COL (large_binary) + recomputation_index=0. Also switches INPUT_DATA_HASH_COL from to_string()/large_string() to to_prefixed_digest()/large_binary() by delegating to the shared _build_record_id_preimage() helper from function_node.py (deferred import to avoid circular dependency). Adds regression test confirming NODE_CONTENT_HASH_COL is absent and INPUT_DATA_HASH_COL uses large_binary in the invocation context preimage. Updates hashing.md site 10 to correctly attribute pipeline_hash_ch to the pod's own pipeline_hash() rather than SideEffectPodStream. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Review response summaryAddressed all 4 Copilot review comments. Genuine code fix (comment 1)The review correctly identified that Commit
All 4565 tests pass. Historical artifact comments (comments 2–4)Comments on |
Summary
docs/reference/hashing.md— a developer reference cataloguing all 14 hash computation sites across 6 usage groups in orcapod-python, with a master index table, per-site structured templates (inputs, algorithm, output format, uniqueness guarantee, exclusions), and a worked example section with concrete hash valuessuperpowers/scripts/hash_audit_example.py— a runnable script that constructs a deterministic example pipeline (scores+attendanceDictSources → Join → FunctionPod/FunctionJobNode + SideEffectPod + PipelineJob) with fixedsource_idvalues and prints all concrete hash values for copy-paste into the docreference/hashing.mdintomkdocs.ymlnav under a new Reference sectionHash sites covered
content_hash()(1),pipeline_hash()(2)source_id(4), per-rowrecord_id(5), Join system tag suffix (6)compute_base_entry_id()(7),compute_pipeline_entry_id()(8)record_id(9),invocation_hash(10)run_id(12),snapshot_hash(13),datagram_uuid(14)Test plan
uv run python superpowers/scripts/hash_audit_example.pyruns without error and prints all hash valuesuv run mkdocs buildpasses (no new warnings fromreference/hashing.md)Closes ITL-529
🤖 Generated with Claude Code