Draft · 0.3.0

A `0.x` draft in production use by adopters: pin the exact draft and runtime release; no compatibility guarantee between drafts.

Draft proposal View current source

RFC 0028: Complete workflow contributor attribution

On this page
  • Status: Draft
  • Type: Standards track (amendment to Draft RFC 0020)
  • Created: 2026-10-23
  • Target: Spec 0.4.0, unpublished
  • Issue: #251

Summary

Preserve every actual contributing rule or forcing exception outside Core's closed disposition. Output version 2 records a typed collection; summary version 2 counts record memberships rather than assigning one representative credit. Execution version 3 selects the complete-attribution model. Signed drift retains those distinctions. This proposal does not change Core resolution. The exact proposed contract is RFC 0020 §5 and §9, mirrored in the workflow companion.

Problem

The #228 amendment chose the least contributor id for a singular contributingRule. Two true, unsuppressed rules producing the same outcome agree under Core; both contributed. Reporting only one drops causal evidence and falsely suggests the contributor counts partition the outcome records. A forcing exception is also a different kind of contributor from a normal rule, even when both have the same pack-local id.

Evidence

The existing conformance/workflow/ records are hand-authored contract fixtures, not executor recordings. Their version-1 envelopes and summaries carry representative attribution and remain unchanged. The separately authored experimental tools/workflow_reader.py targets RFC 0024's workflow-version-2 admission-proof proposal and output-version-1 envelopes without attribution; it does not implement #228's bulk fields. Its retained recordings, provenance and historical pins are not upgraded by this proposal. No full workflow consumer upgrade is claimed.

The new RFC-owned fixtures are also hand-authored. They include opposite pack orders, two compatible rules, two compatible forcing exceptions, typed same-id namespaces, suppressed and false rules, bypassed normal rules, fallback and non-outcome cases. An explicitly hypothetical failed outcome-value resolution records no contributor credit; it is not an executed Core 0.3.0 value feature. A failed evaluation has no output envelope. Runtime issue #305 owns retaining actual evaluator contributor evidence in that repository; this RFC does not implement it.

Specification

Output version 2 conditionally carries contributors: [{kind, id}]. Kind is rule or forcing-exception. Preserve every actual member, sort by kind then exact Core id, reject duplicates and empty/null collections, and keep one homogeneous kind per output. False, suppressed, skipped, escalating and discarded candidates receive no credit. Fallback and non-outcomes omit the member; failed evaluations have no outputs. The 4096-entry ceiling is subordinate to the 65536-byte output envelope ceiling; exceeding either refuses the input or prevents output admission, never truncates or elects a representative.

Summary version 2 keeps byRule[outcome].contributors as exactly two kind maps: rule and forcing-exception. Every member increments once per output. Fallback counts records separately. One record with two contributors is one outcome count and two contributor memberships. For N outcome records, F fallback records and M memberships, each individual count is at most N−F, and N−F ≤ M ≤ 4096×(N−F). Record and outcome counts retain their own invariants.

Execution version 3 requires model-2 outputs and summaries throughout, including empty stages. Execution version 1 preserves historical semantics; version 2 is already reserved by the separate Draft RFC 0024 admission-proof proposal. Choosing 3 avoids conflating or adopting that proposal. Workflow document version 1 and selection version 1 retain their existing forms. Drift version 2 subtracts the typed per-identity membership counts; attribution-only changes need not appear in its disposition-only record changes. Mixed-model comparison is version-unread.

The new draft resource is schema/workflow-contributors-2.schema.json, with $id https://judgmentpack.org/schema/0.4.0/workflow-contributors-2.schema.json. Its name describes the attribution model, not workflow document version 2. The historical schema stays unchanged.

Alternatives

No change preserves the misleading single-credit partition. First/last/least-id representatives all discard valid contributions. A complete collection as an ungoverned extension or profile leaves consumers unable to agree on summary or drift semantics. Product-only display cannot repair retained evidence. Rewriting the still-Draft version-1 form would be simpler but silently relabels retained representative records and experimental consumers, so explicit versions are used.

Compatibility

Older readers refuse new exact selectors. New readers may support historical forms separately, labeling their attribution representative/incomplete or unavailable, never complete. A singular representative is not automatically a singleton complete set, and its id does not identify its namespace. No deterministic complete migration exists without sufficient original evaluation evidence or replay. Rebuild all transitive pins after replay and preserve original bytes.

Reader, writer and semantic compatibility are intentionally broken at the new attribution model. Core 0.3.0 schema, corpus, published artifacts and resolution remain unchanged; no release version is bumped by this change. The target 0.4.0 is a planning identifier and not an immutable release.

Security and privacy

Counting a duplicate or suppressed member can inflate apparent influence. Typed identities, strict forms, bounded arrays, exact envelope pins and independent summary recomputation expose such inconsistencies within retained evidence. A coordinated rewrite can still agree. A bulk reading proves neither condition truth nor actual completeness, authorization or safety. Complete contributor lists may disclose more pack structure than a representative; use only synthetic public examples.

Conformance

The Python and JavaScript bounded accounting experiments read the same hand-authored projections and caller-supplied admitted Core pack bytes. They check exact pack/envelope pins, identity kind, pack membership, declared outcome association, collection ordering and counts, then independently compute typed signed drift. They do not share an accounting helper. They are one-author, same-vendor-assisted experiments, not independent organizational interoperability evidence, full workflow readers, or a conformance corpus. Their result bulk-consistency is local experimental output, not the workflow-verifier's reading event.

Mutation cases cover omissions with fixed summary/pins, duplicate/unknown ids, wrong kind/outcome, non-outcome credit, malformed absence/empty forms, count/digest drift and mixed versions. A coordinated omission with rebuilt pins and summary intentionally passes structural accounting; its independently authored expected membership disagrees. This makes the limit visible instead of claiming causal proof. Full workflow recording, both full readers and replay remain acceptance evidence to obtain under RFC 0020 §11.

The bounded experiments check workflow integer token spelling and the 128-character token ceiling before conversion. Caller-admitted exact Core pack bytes retain their own number and size domains; neither whitespace nor the escaped pack transport string is a workflow value. An explicit local aggregate experiment limit is 33554432 bytes for canonical projections plus supplied pack bytes, across both sides of drift. The JavaScript stdin transport separately caps its full UTF-8 JSON wrapper at that size before decoding. These local limits do not define a Core pack ceiling or a full workflow conformance claim. Every emitted negative regression event is validated against the closed report schema. Missing required selectors are input-malformed; unsupported integer selector values are version-unread.

Implementation

A Runtime can retain all final contributors while resolving and sign that evidence in its audit; a Runner can copy it into each output envelope and independently accumulate the typed membership counts. A second implementation can replay the pinned pack and inputs, build the same sorted set, and check a separately implemented summary/drift reader. No consumer upgrade or release is asserted by these plausible implementation routes.

Unresolved questions

Public RFC comment, the governance review record and maintainer dispositions remain merge gates. The explicitly authorized temporary same-vendor review exception while the other vendor is unavailable does not constitute cross-vendor evidence. This Draft does not mark those gates complete, waive the repository process, or claim a full execution recording. The future consumer release pin that supplies complete evaluator evidence must be recorded before asserting full workflow support; RFC 0020's old Runtime pin does not supply that evidence.