Skip to content

bug(unic-archon-dlc): a review node produced thirteen findings and recorded them nowhere #438

Closed as not planned

Description

@orioltf

What happened

implement-review-precheck ran for 5m07s during run 2's build leg and wrote two lines to the dispatch log: Started, Completed. The run's artifacts directory was empty. No file in the worktree carried its output.

It had produced thirteen findings. They were recovered only by querying Archon's SQLite directly — ~/.archon/archon.db, table remote_agent_workflow_events, event_type = node_completed, field node_output. The node's own closing line reads "This node posted nothing."

Several were real and two were later confirmed independently by a separate review pass, including a token-drop defect that had already shipped into a committed snapshot.

Why this is a defect and not a design choice

The Box calls it a "local non-posting code-review pre-check". Non-posting is a design choice. Non-recording is not the same thing.

A reviewer at the gate cannot read these. The run's own report cannot cite them. A run that found thirteen real problems is indistinguishable from a run that found none — which is the false pass this whole lifecycle is supposed to prevent.

For contrast, in the same run: goals-check wrote its verdict into the pull request body, and the unic-dlc-pr-review Box posted eleven threads. The gap is one node's, not the lifecycle's.

The open question, to be grilled before criteria

Where does a non-posting node's output go, so that it is readable without a database client and citable by the report?

Candidates, none decided: the run's artifacts directory · a file in the worktree the next node reads · the run's own event log made readable by a command · a summary the posting node folds in.

Related

Same family as #437 — that one is the gate has no reader; this one is the chain has a reader and discards what it read.

Full evidence: docs/research/2026-08-31-dlc-run-2-findings.md.

Activity

  1. added
    bugSomething isn't working
    needs-specsEnough info from reporter; ready to write a spec
    p1High priority
    on Sep 1, 2026
  2. added
    wayfinder:taskWayfinder ticket: do the thing
    wayfinder:grillingWayfinder ticket: decide it by grilling
    and removed
    wayfinder:taskWayfinder ticket: do the thing
    on Sep 3, 2026
  3. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    How to start this session

    Written 2026-09-03 by wayfinder-orchestrator-4. This is a grilling with the maintainer in the room, not an
    implementation. It produces decided acceptance criteria on this ticket and a list of what it did not decide. It
    writes no YAML.

    ready-for-agent stays off until the maintainer approves the criteria this session produces.

    What to invoke, and the one step of it to skip

    Enter with /wayfinder 456 438, typed by the maintainer. #438 is a child of the run-3 map, so that is the
    map-native entry: it loads the map at low resolution and — the part that matters — claims the ticket by
    assigning it before any work
    , so a second session skips it. Nothing else assigns, and the frontier query reads
    assigned=0, so without this two sessions can take the same ticket.

    Then stop following the skill at its step 4, and do not close this issue. /wayfinder's "Work through the
    map" resolves a ticket by posting the answer, closing it and appending a line to Decisions-so-far. That is
    right for a decision ticket and wrong here: this stream grills a bug ticket, puts the criteria in that same
    ticket's body, and implements the same number — #452, #441 and #430 all went that way. Closing #438 would split
    one ticket into two and break the ADO mirror, which points at this number.

    So: /wayfinder to enter and claim; this opener governs what happens at the end. If the two disagree anywhere
    else, say so rather than picking one.

    For the grilling itself the maintainer types /grill-with-docs. Not /grilling alone: .agents/skills/grill-with-docs/SKILL.md
    carries disable-model-invocation: true, so no agent can invoke it, and #441 spent six rounds on /grilling
    with nowhere durable for the decisions to land. grill-with-docs composes domain-modeling, which is what gives
    a settled decision a home — and this ticket needs that twice over, because it turns on three things with
    confusingly similar names.

    Read order

    1. This ticket's body, then feat(unic-archon-dlc): the /specs gate asks for approval of an artefact nobody reads #437's — this ticket is the chain has a reader and discards what it read, feat(unic-archon-dlc): the /specs gate asks for approval of an artefact nobody reads #437
      is the gate has no reader. They interlock and neither swallows the other.
    2. docs/research/2026-08-31-dlc-run-2-findings.md, the rows for this finding.
    3. apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-build.yaml — the
      implement-review-precheck node in full, then lines 16, 189–192 and 255. Those four places are where the
      trap below lives.
    4. #456 § Notes — the class rule. This ticket is an
      instrument: it changes whether a result can be read, not what the chain produces. That is why it lands
      before run 3 and why it must not grow into a change to what the node reviews.
    5. Root AGENTS.md § "Acceptance criteria are prose", before writing a criterion.

    The one trap that costs an hour

    "The run's artifacts directory" is not one place. It is two, with opposite properties, and this ticket's first
    candidate does not say which.

    Name Where Reviewable?
    $ARTIFACTS_DIR outside the repo, under ~/.archon/workspaces/<workspace>/artifacts/, always gitignored No. Invisible in a pull request, gone when the run ends, and reused on resume, so a stale file from a failed attempt is still there
    <artifacts_dir>/<slug>/ this Plugin's own config key, default workflows/, repo-relative and deliberately committed Yes

    Both are in unic-dlc-build.yaml, and the file uses them for opposite purposes in the same breath: line 16 says
    the engine refuses a terminal completed unless $ARTIFACTS_DIR/evidence.json exists, and line 255 says
    NEVER stage anything under $ARTIFACTS_DIR. Meanwhile lines 189–192 put the session's real artefacts —
    issues.json, build-state.json, the PRD — under <ARTIFACTS_DIR>/<SLUG>/, committed.

    There is a third similarly-named home, .archon/workflows/, which holds the Box YAMLs and nothing else.

    So a criterion that says "the node writes its findings to the artifacts directory" is satisfiable in a way
    that fixes nothing
    — write to $ARTIFACTS_DIR and the thirteen findings are exactly as unreadable as they
    were, while the criterion passes. Name the home in every criterion that names a path. Memory:
    reference_archon_artifacts_dir.

    The decision this ticket must actually make

    The ticket asks "where does a non-posting node's output go". That is the right question and it hides a prior
    one the four candidates do not ask:

    Who is the reader, and when do they read? The three answers pull in different directions:

    • A human at the gate, during the run. Then it must exist before the gate node runs, in a place a human can
      open without a database client.
    • A reviewer on the pull request, after it. Then it must be committed, and $ARTIFACTS_DIR is disqualified
      outright.
    • The next node in the DAG. Then a file in the worktree is enough and neither of the above matters.

    Settle the reader first. Three of the ticket's four candidates are answers to different readers, which is why
    they look like alternatives and are not.

    Questions the ticket does not ask

    1. Is this node's silence the rule or the exception? The ticket contrasts it with goals-check and the
      pr-review Box, both of which record. Before writing criteria, count the non-posting nodes across all four
      Boxes and check whether each records. A fix scoped to one node leaves its siblings silent, and this is a
      plugin whose defects come back one node at a time.
    2. What happens when the node finds nothing? A run with no findings and a run whose findings evaporated must
      not look the same — that is the ticket's own argument, and it applies to its own fix. An absent file is
      exactly the ambiguity being fixed.
    3. Does the report cite, or restate? "Citable by the report" can mean the report names a path or reproduces
      the content. One rots when the file moves; the other duplicates and drifts.
    4. What does a resumed run do with the previous attempt's file? $ARTIFACTS_DIR is reused on resume, and
      this plugin has already been bitten once by a stale presence-checked artefact certifying a new attempt.
    5. Is thirteen findings' worth of prose the right size for wherever it lands? A pull-request body caps at
      4000 characters on Azure DevOps and the run's own report is already near that in practice.

    What this grilling must not do

    Before you write the criteria, the four reads — twice

    From root AGENTS.md, and #441 proved on 2026-09-03 that six grilling rounds do not retire them:

    • Read them as one set, hunting the gap between two that an implementer fills with a defensible-sounding
      decision.
    • Turn the diagnosis on the cure. This ticket says a node's output vanished because nothing wrote it down.
      Ask what the fix still does not write down.
    • Ask which criteria are satisfied by changing nothing, and say so in the ticket rather than leaving someone
      to hunt for work that is not there.
    • Close by listing what you did not decide.

    And the half adopted 2026-09-03: the four reads run twice — once here on the criteria, once at review time
    against the diff with the surrounding unchanged text in view. #441's gate was inert because of an unchanged line
    three lines above the criterion that satisfied it, which no reading of the ticket could reach. Memory:
    feedback_four_reads_against_the_diff.

    And one this ticket is unusually exposed to: a rule stated only in an AGENTS.md has no reader at run time.
    #430 measured it — AGENTS.md said "name no tool" and the plugin broke it in five places, unnoticed. If a
    criterion here ends at "the ADR says the node records its output", ask what reads that ADR while the node runs.
    Memory: feedback_rule_with_no_runtime_reader.

    On landing

    Do not close this issue, and do not write to #456's Decisions-so-far. The criteria go in this body, with a
    "what this did not decide" section, and the label stays needs-specs. The maintainer approves; ready-for-agent
    follows; the implementation opener is written at dispatch, not now. #456's Decisions-so-far gets its line when
    this ticket is closed by its implementation, not by its grilling.

    Leave the assignment in place — the claim is what stops a second session taking it while it waits for approval.

    Azure DevOps: this ticket's mirror is 43035, 5 points,
    under Feature 42975, iteration 2026_08 - R 3.6. Re-point it if the grilling grows the ticket — #430 was
    sized at 5 as an install fix and came out of its grilling as a config abstraction worth 13. A scalar field
    replaces cleanly: az boards work-item update --id 43035 --fields "Microsoft.VSTS.Scheduling.StoryPoints=<n>".
    The mirror carries title, link, points and state — never a copy of the body.

    Report back

    BEFORE YOU FINISH, AND WHENEVER YOU LEARN SOMETHING THAT WOULD HAVE CHANGED THIS PROMPT, SendMessage to the
    live orchestrator seat — confirm the name with ListAgents first, and if no seat answers, comment these four
    things here instead:

    1. what you expected
    2. what happened
    3. the command or file that proved it
    4. whether it changes only this ticket, or every session in this repository

    Send it when you learn it, not only at the end. A session that dies unreported takes its learnings with it.

  4. self-assigned this
    on Sep 3, 2026
  5. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    Closed as not-a-defect — the premise did not survive a direct read

    Grilled 2026-09-03. The thirteen findings were recorded. They are in a committed file on run 2's pull-request branch, and they were there the whole time.

    What the ticket claimed, and what is true

    Claim in the body Measured
    "No file in the worktree carried its output" False. workflows/profile-card/report.md § 4 carries all thirteen, verbatim.
    "Recovered only by querying Archon's SQLite directly" That is the route the reporter used, not the only one.
    "A run that found thirteen real problems is indistinguishable from a run that found none" False for this run.
    "The run's artifacts directory was empty" True, and it is what seeded the wrong conclusion. See the trap below.

    The evidence

    unic-dlc-build.yaml:578 is the only reference to this node's output anywhere, and it is inside the report node, which folds $implement-review-precheck.output.findings in verbatim under a subsection labelled "Local code-review pre-check (not posted — /pr-review posts)".

    That path ran. In ~/.archon/archon.db, run 66c36ce5:

    report   node_started 2026-08-31 18:03:47 UTC → node_completed 18:06:40
    open-pr  node_started              18:06:40 → node_completed 18:08:11
    

    In DXP-DesignSystem, git show c66eac9:workflows/profile-card/report.md | sed -n '195,256p' prints the thirteen — ## Standards with four hard findings and three smells, ## Spec with six — ending on the very line this ticket quotes as proof of loss, "This node posted nothing." The commit is dated 20:07:19 +0200, which is 18:07:19 UTC, inside the open-pr window above, so the run committed it. git branch -a --contains c66eac9 lists origin/feature/43004_build-profile-card, so it was on PR 5825 and reviewable.

    The trap that produced the report

    "The artifacts directory" is two directories. $ARTIFACTS_DIR resolves outside the repo under ~/.archon/workspaces/<name>/artifacts/, is always gitignored, and is reused on resume. It was indeed empty here — evidence withheld evidence.json on the red verdict, correctly. The repo-relative Session dir, <artifacts_dir>/<slug>/, is a different place, is deliberately committed, and is where report.md landed. Reading the first and concluding about the second is the whole error. Anyone writing a criterion in this plugin should name the home every time a path is named.

    What survived, and where it went

    Surveying the other three Boxes for the same shape found the defect this ticket described, in a different Box. /qa emits three prose fields that nothing reads and nothing writes to disk — e2e.summary, coverage-gate.summary, uat-prep.criteria. That is filed as #458, with line evidence. /qa is not on run 3's path, so it is out of scope for the #456 map and carries no wayfinder:* label.

    /build is the well-behaved Box here: its prose has a reader and a committed home.

    What was deliberately not turned into work

    The one weakness left in /build is that the precheck's findings reach disk only through report, four nodes downstream. That failure has never occurred — verification and evidence both carry always_run, and evidence exits 0 when it withholds, so a red verdict still reaches report. Adding a durability mechanism to the Box that run 3 measures, for a failure nobody has seen, is speculative work in the worst possible place. If a run ever loses a node's prose to an error between implement-review-precheck and report, that run is the ticket.

    Corrections this closure carries

    docs/research/2026-08-31-dlc-run-2-findings.md row 35 and its § F3 summary line both assert "nowhere a human or the report can reach". Both are wrong and are being corrected by the orchestrator seat that owns the file.

  6. added
    resolvedImplemented; ready for a PR
    and removed
    needs-specsEnough info from reporter; ready to write a spec
    on Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app:unic-archon-dlcbugSomething isn't workingp1High priorityresolvedImplemented; ready for a PRwayfinder:grillingWayfinder ticket: decide it by grilling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions