Skip to content

proof: effort-local causal edges force feature reasoning into domain Efforts (specificity loss, Effort bloat) #278

Description

@tonyketcham

Describe the problem

Since #251, every create-time and lifecycle relation must stay inside one Effort:
derives_from, supersedes, invalidates, cites, resolved_by,
mitigated_by, evidence and rejected_by. #251 correctly removed an
inconsistency: commits used to succeed that reads then hid. The resulting rule,
though, forces an uncomfortable choice whenever one coherent piece of work
builds on reasoning recorded in several Efforts. That is the normal case once a
project has domain Efforts, such as "graph semantics", "geometry engine",
"editor UX" and "export".

Versions: flatbread@1.2.0, @flatbread/proof@1.2.0.

Real-world example

A downstream project planned a feature: a family of distortion nodes. It needed
six durable Decisions. Their causes lived in four existing Efforts:

  • node registry contracts and cache identity (graph Effort);
  • authoritative geometry, tolerance semantics, the packed path format, and an open
    "excessive geometry" Risk (geometry Effort);
  • "graph is the only authoring surface" and "distinguish preview from
    authoritative geometry" (editor Effort);
  • "define export behavior for every effect" (export Effort).

The options were:

  1. Create a feature Effort. The feature is then readable as one thread, but
    no Decision can derive_from its real causes. Links degrade to ids written in
    prose, which reads can't follow, the validator doesn't check, and Retract
    doesn't strip.
  2. Split the feature across domain Efforts so that each Decision can link to
    its causes. We chose this: 3 Decisions in the graph Effort, 2 in the geometry
    Effort and 1 in the editor Effort. The feature now has no single place to read
    it. Recall needs three Effort-scoped queries plus prose cross-references, and
    links to the export Effort's Constraint are still impossible.
  3. Duplicate or broaden. Copy upstream Constraints and Decisions into the
    feature Effort, or widen a domain Effort until everything fits.

All three options cost specificity. Option 2 is also the direct cause of
Effort bloat and scope creep:

  • Effort size: domain Efforts become catch-alls for every feature touching
    them. They reach the 25-record read cap sooner, and each feature's reasoning
    is interleaved with unrelated threads.
  • Collateral rejection: larger Efforts make the AcceptDecision
    rejectSiblings: true default more destructive, because more unrelated
    proposals sit together (see proof: AcceptDecision rejectSiblings default rejects unrelated proposals across the whole Effort #277).
  • Risk mitigation: MitigateRisk can only point at a Decision in the Risk's
    Effort. A feature Decision that actually mitigates a domain Risk must either
    move into that domain Effort or leave the Risk permanently open.
  • Placement pressure: an agent optimizing for linkability picks the Effort
    with the most linkable causes, not the Effort that best describes the work.
    Effort boundaries stop meaning "one coherent thread".

Proposed direction

Keep the lifecycle edges effort-local. supersedes, invalidates,
resolved_by, mitigated_by and rejected_by change another record's state,
so the #251 boundary is right for them. Add a reference path for causal
context:

  1. Cross-Effort derives_from (and possibly cites) as read-only references.
    • Allow them to point at a record in another Effort.
    • Never write reverse projections into the foreign record.
    • Validate target existence at create time.
    • Render them in digests as foreign checkpoints with their Effort id and
      current state, followed only with an explicit flag such as
      relations --include-foreign.
    • Retract strips them globally, or reads report them as dangling explicitly
      rather than silently dropping them.
  2. Or declared Effort dependencies. An Effort declares depends_on: [<eff-id>], and cross-Effort causal edges are allowed only into declared
    dependencies. This keeps the graph intentional and gives reads a bounded
    frontier.
  3. Cross-Effort mitigation. Allow MitigateRisk to reference an accepted
    Decision in a dependent Effort, or document the intended pattern for a feature
    Decision that mitigates a domain Risk.

Acceptance

  • A feature Effort can hold its own Decisions and link each to accepted records
    in the domain Efforts it builds on, without moving records or duplicating
    them.
  • Bounded reads stay bounded. Foreign references cost at most one checkpoint
    line each and are never expanded implicitly.
  • proof: reject cross-effort create-time relations and report legacy edges #251's guarantee still holds: nothing commits that a read then hides.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    corecentral engineenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions