Skip to content

forgeplan_get returns no links, so a linked artifact looks identical to an orphan #447

Description

@explosivebit

Summary

forgeplan_get (MCP) returns a rich artifact object — ~20 fields including r_eff_score, depth, parent_epic, valid_until — but no links. An artifact with five edges and an artifact with none are indistinguishable in the response.

Found on forgeplan 0.34.0. It cost a wrong conclusion in a live session, which is why it is worth reporting rather than working around.

What happened

Asked to check whether two specs were orphaned, I called:

forgeplan_get(id: "SPEC-003")

The response carried r_eff_score: 0.0, status: "draft", and no link field of any kind. I reported the spec as an orphan.

It was not. The graph, in the same workspace and the same minute:

$ forgeplan graph | grep -E "SPEC-003|SPEC-004"
    SPEC-003 -->|based_on| PRD-001
    SPEC-004 -->|refines| SPEC-003
    ADR-008 -->|informs| SPEC-004

Both were correctly linked the whole time. The real finding was different and less obvious — no evidence pointed at them, so r_eff was 0 and they were stuck in draft.

Why the shape of the response makes this likely

The object looks complete. Twenty-odd fields, several of them niche (predicted_number, id_canonical, assigned_number). Against that background, a missing links reads as "this artifact has none", not as "this tool does not report them". Absence of a field and absence of data are the same thing to the caller.

It is also the one question get cannot currently answer about a single artifact. forgeplan graph answers it for the whole workspace and needs grepping down; there is no per-artifact equivalent.

Suggested direction

Include the artifact's edges in forgeplan_get — inbound and outbound, with relation kind. Something like:

"links": {
  "outbound": [{"target": "PRD-001", "relation": "based_on"}],
  "inbound":  [{"source": "SPEC-004", "relation": "refines"},
               {"source": "EVID-011", "relation": "informs"}]
}

Inbound matters as much as outbound: "which evidence supports this" is exactly the question behind an r_eff of 0, and it is invisible from the outbound side.

If including them by default is too heavy, an explicit empty array ("links": [] when there are none) would already remove the ambiguity — the caller could then tell "no links" from "not reported".

Environment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions