Skip to content

bug(unic-archon-dlc): the config maps commands to nodes and the Boxes name tools, so a check runs by luck or not at all #430

Closed

Description

@orioltf

What this is

A Box cannot check a claim about a build, a lint, a type-check or a test run, and the reason is three
faults stacked on one another. Grilled with the maintainer on 2026-09-03; this body carries the decisions
and the criteria. The two comments below carry the measurements and two corrections to what this body
first said, and they stay on record.

Axis What is wrong Where
Capability an Archon worktree may or may not carry installed dependencies, and no Box asks for them 12 of 16 worktrees on the maintainer's machine have node_modules, 4 do not, and no Box instructs any node to install
Instruction unic-dlc-pr-review instructs no build, lint, type-check or test command anywhere, and neither does the code-review Method it hosts grep -cE "pnpm |lint|typecheck|install|node_modules" unic-dlc-pr-review.yaml → 0
Configuration the config maps a command one key per intended node, so a command has an owner instead of a home, and a Box names a tool where the config says nothing unic-dlc-build.yaml:403 falls back to the literal pnpm test

The three interact. Run 2's verification reported PASSED and really did run a green suite, because that
worktree happened to have dependencies and the Box happened to fabricate the right command for a pnpm
repository. Both were luck. On a Python or a .NET Consumer the same node runs a command that does not
exist and reports a failure that has nothing to do with the code.

And run 2's honest "node_modules is absent in this worktree, so neither axis could execute" came from a
sub-agent volunteering a check nobody asked it for. That is the instruction axis: an install alone
changes nothing in pr-review, because nothing there is told to run.

Why it matters more than it looks

The review's whole value is checking claims the author makes. On run 1's PR the author claimed a green
build, a clean lint, clean types and a passing test run, and none of the four was checked, so the verdict
rested on reading the diff alone. DXP-DesignSystem has no pipeline, so when a Box cannot run a check,
nothing mechanical ever runs it. A human on their own machine is the only path, and both runs 1 and 2
ended that way.

The decision

The config becomes the abstract layer that maps what a software development process needs, and every
Box reaches the whole of it.
The plugin names no tool, ever. A Consumer fills in whatever its stack
uses, and a node decides at run time which of those needs it has.

Three rules carry the weight:

  • A key names a need of the development process, never a tool. test is a need. pnpm test is a
    tool. check-types is somebody's script name; typecheck is the need. This is the rule already
    written at AGENTS.md:57 for formatter exclusions, applied to commands.
  • Discretion to add, never to subtract. Any node reaches any key it judges it needs. A short floor
    is mandatory at the two gates that advance work, and abstaining there is a reported non-result, not
    silence.
  • A command that cannot run is never a pass. Today /qa skips without blocking and /build
    fabricates. Those are the same defect from opposite ends.

The three-option menu this body used to carry is spent. Options 1 and 2 collapsed into one when the
install cost was measured (4.4 s, 16 MB, warm store, APFS). Option 3 is unavailable, because #430 is an
instrument for run 3 and an instrument that cannot observe is broken, not honest.

Acceptance criteria

  1. The config declares the SDLC's needs in one flat block, named sdlc_needs. The template
    /unic-archon-dlc:setup writes gains a top-level sdlc_needs block holding exactly nine nullable
    keys: install, build, test, e2e, lint, format, typecheck, dev, coverage. Every value defaults to
    null. Amended 2026-09-03 19:22: the ninth key comes from the maintainer's ruling on did-not-decide item 8,
    recorded as criterion 20; the first version of this criterion said eight. Amended 2026-09-03 19:35, found by
    DLC-430 under hold:
    README.md § Configuration reference gains one row per key in the same PR.
    commands/setup.md:262 calls that table the source of every default and :285 forbids asking the operator for a
    key the table omits, so criterion 16's proposals are illegal by /setup's own rule until the rows exist. The name is snake_case, and that is measured rather than chosen by taste: every key in the
    Consumer's live config is snake_case without exception (artifacts_dir, coverage_threshold,
    fresh_context_red_green, out_of_scope_dir), so sdlcNeeds and SDLC_needs both lose.

  2. The block states its own rule, and states which keys nothing reads yet. Its comment says that a
    key names a need and never a tool. It also says that build, lint, format and dev have no node
    reading them on the day this lands, and are declared anyway because /setup writes this file once and
    thereafter only reports on it, so a key added later costs another reconfigure in every Consumer.

  3. bootstrap emits the whole block as one object, and no prose assigns a key to a node. In all
    three Boxes the bootstrap output schema carries sdlc_needs as a single object field. The per-node
    scalars test_command and e2e_command are gone from those schemas. A reader can check that no
    node's prose says a given key belongs to it.

  4. No Box that runs a command names a tool. Three sites go: unic-dlc-build.yaml:403's
    else \pnpm test`, unic-dlc-build.yaml:51's (e.g. "pnpm test")in the inference instruction, andunic-dlc-qa.yaml:134's e.g. pnpm test --coverage. After this, a grep for pnpm across the three Box files returns **nothing at all**. **Corrected 2026-09-03 19:35 (DLC-430):** the first version said "nothing outside slopcheck"; slopcheckholdsnpm (unic-dlc-build.yaml:84, :130), never pnpm, so an implementer expecting survivors there would read zero as over-deletion. unic-dlc-explore.yaml:101is the onepnpm` left in
    the plugin's workflows and § Out of scope keeps it.

  5. The two e2e_command keys are retired, and the retirement is stated as deliberate. /qa's
    qa.e2e_command ?? build.e2e_command two-tier resolution is replaced by the single sdlc_needs.e2e.
    The per-Box override is removed on purpose, because all four values are null in the only Consumer
    that exists, so nothing has ever used that tier. The ADR of criterion 12 says so, rather than leaving
    it to read as an oversight. Amended 2026-09-03 by the orchestrator, four-reads pass before dispatch:
    the two documents that describe those keys change in the same PR — README.md's config table
    (build.e2e_command, build.coverage_threshold rows) and docs/boxes/unic-dlc-qa.md (the resolution
    line and its config table). Nothing else in this ticket named them, and a reader of either would have
    been told a key exists that the config no longer has. Third site, added 19:35 (DLC-430): commands/setup.md:273,
    the **build** line of Step 6's field list, names both retired keys and changes in the same PR.

  6. Each Box installs once, at bootstrap, and says what it did. One Archon worktree serves a whole
    run and the build Box's RED and GREEN phases are fresh contexts inside that same worktree, so one
    install covers everything. All three Boxes install, with no per-Box exception, and pr-review is not
    exempt even though criterion 11 gives it no instructed check: run 2 recorded a sub-agent volunteering
    a check of its own and being unable to execute it, so an install there decides that case on merit
    instead of on which worktree the run drew. One uniform rule is also less to remember than a rule with
    an exception. bootstrap reports either that it ran sdlc_needs.install, or that sdlc_needs.install is
    not declared. Where it is not declared, dependencies may still be present by the luck this ticket
    exists to remove, so that report is what stops a later green check reading as proof of a deliberately
    built environment.

  7. A command outcome has three states, and unresolved is never a pass. Every node that runs a
    command reports pass, fail or unresolved. One unresolved covers both causes, the command not
    being declared and the command being declared but unable to run. The cause goes in the prose, not in
    the state. A node names which need went unresolved. A pass carries the counts the command reported,
    and a pass with a zero count is reported as suspicious rather than as a green result, because that
    is the shape a command declared against the wrong target takes.

  8. Where a Box has a gate that advances work, unresolved holds it, and nowhere else blocks.
    /qa's merge and /build's evidence are those gates. pr-review has no such gate, and the
    per-slice loop inside run-build is not one either, so an unresolved type-check there reports and the
    loop continues. Rewritten 2026-09-04 20:45 by the orchestrator on the maintainer's ruling (Q10 of bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's
    grilling: "a"), because bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439 changes evidence's mechanism after this ticket lands.
    The verdict
    evidence emits carries three states, pass, fail or unresolved, in the JSON it prints to stdout and in
    the file it writes, and no reader treats unresolved as green. The reader of that verdict is a node when:,
    never the engine: evidence_policy checks presence only, and once bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439 makes the file unconditional it fires
    only when evidence itself crashes before writing, which is the backstop bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439 keeps it for. Whether the
    file is written always or only on green, and which node carries the when: that stops open-pr on red,
    are bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's decisions. This ticket edits verification and evidence for the third state; the sentence in
    verification's and goals-check's prompts that tells the reader what evidence does with their output
    states the three-state outcome, and both prompts carry the same sentence, so both change. bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439 rewrites
    that sentence again for always-write and the backstop, against the tree this ticket leaves, and owns the
    evidence node's comment block whole (the DAG loader parses script-node comments for $node.output
    tokens, so nobody tidies it in passing). Between the two merges the printed verdict has no reader, by
    design
    : today nothing in the Box reads $evidence.output (report reads verification and goals-check
    directly), and the when: that will consume it is bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's decision. A reviewer who finds a field with no
    reader in this ticket's diff has found this sentence, not a defect; criterion 10's block reads the unresolved
    needs from verification's output and needs nothing from evidence. /qa's merge when: holds on
    unresolved the same way. Added 19:35 (DLC-430): the plugin AGENTS.md § Plugin doctrines
    evidence-gate bullet (AGENTS.md:91) says the node writes "only when both are true"; that sentence is revised in
    the same PR, one layer up from ADR-0034, the same way criterion 5 names the documents that describe retired keys.

  9. The floor: /qa's merge gate and /build's evidence verdict require a test outcome. No test
    outcome at either is unresolved, which criterion 8 then holds. No other need is mandatory anywhere.
    (Reworded 2026-09-04 with criterion 8: "cannot advance" described the withholding mechanism bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439 retires;
    the floor itself is unchanged.)

  10. A check a Box could not verify reaches the reader as its own visible block, not as a sentence in
    a paragraph.
    Any summary that carries a check outcome or an install report also carries, in a
    structurally separate block a developer skimming cannot pass over, the needs that went unresolved
    and whether sdlc_needs.install was declared. A reviewer checks this by reading the summary's shape,
    not its wording. pr-review's summary states, in that same block, which commands the config
    declares and that this Box executes none of them by instruction.
    Criterion 11 is the reason, and
    without this sentence that admission lives only in this ticket, where the developer reading a review
    never sees it. Amended 2026-09-03 by the orchestrator, four-reads pass before dispatch: the block is
    durable — it lands in a file under <artifacts_dir>/<slug>/, the repo-relative Session dir, and a
    block that exists only in a node's console output does not satisfy this criterion. Without this sentence
    /qa satisfies it in scrollback: its e2e and coverage-gate summaries have no reader in the DAG and
    the Box has no report node, so the block would die with the worktree exactly like the summary it sits
    in. Found by DLC-438-grilling while grilling bug(unic-archon-dlc): a review node produced thirteen findings and recorded them nowhere #438, verified from the orchestrator seat.

  11. pr-review gains no procedure that runs a check against an author's claim. That procedure
    belongs to a Method, not to the Harness (ADR-0030), and its home is feat(unic-archon-dlc): the review angles become a Method of ours, harvested from unic-pr-review and rewritten stack-agnostic #433 as a named review angle.
    So the title of this ticket stays partly true after this lands: pr-review still runs no lint and no
    type-check against a claim. What it can no longer do is stay quiet about that. This ticket's body says
    so rather than leaving a reader to discover it.

  12. An ADR records the config-as-abstraction decision, referenced by slug and never by number. It
    carries the need-not-a-tool rule, the discretion-to-add-never-to-subtract rule, the floor, and the
    retirement of the two e2e_command keys. It also records three things a later reader would otherwise
    re-derive. Why the block is sdlc_needs: a key names a need, so a name that named the tools a
    need resolves to would encode the opposite of the block's own rule, which is why toolchain lost;
    commands is reserved twice over and capabilities is taken. Where SDLC comes from: Anthropic's
    The AI-Native SDLC playbook (https://claude.com/blog/the-ai-native-sdlc-playbook), which defines
    the lifecycle as idea to production across Plan, Design, Build, Test, Deploy and Maintain, and names
    build, test and lint commands alongside linting, formatting and type-checking. Eight of the nine keys come
    from that vocabulary; coverage comes from criterion 20 and the ADR says so. And that criterion 16 widens an existing sweep rather than adding a third,
    with the reason: a sweep that re-reads the same manifests for a second purpose is the drift this
    plugin keeps filing defects about.

  13. The delivery is named, and it ends inside the Consumer. commands/setup.md is in GUARDED in
    packages/release-tools/scripts/lib/changelog-gate.mjs, so the PR carries a version bump and a
    changelog entry. Reaching run 3 then needs claude plugin update in DXP-DesignSystem, whose
    .claude/settings.json sets "autoUpdate": false, then /unic-archon-dlc:setup, which reports
    the missing block and changes nothing because the config is tenant-owned, then
    /unic-archon-dlc:setup reconfigure, which is the one override that rewrites it. A criterion that
    ended at "the template gains a block" would be satisfied by a change run 3 never sees.

  14. After the delivery, DXP-DesignSystem's config carries real values for sdlc_needs.install and
    sdlc_needs.test.
    Without them criterion 4 has removed the fabricated fallback and criterion 9 holds
    the gates, so run 3's build leg stops at unresolved. That is the correct failure and it still stops
    the run.

  15. The two test_command surfaces stay distinct, and a reader can tell which is which. /tickets
    writes a per-slice test_command into issues.json (commands/tickets.md:165), read by the RED and
    GREEN phases at unic-dlc-build.yaml:279 and :296. That surface is untouched. Only bootstrap's
    project-wide inference becomes sdlc_needs.test. The name collision that made this hard to see goes
    away, and nothing rewires the per-slice command by mistake.

  16. /setup proposes the values from the stack it detected, and never asks blind — by widening the
    sweep it already runs, not by adding a third.
    Step 4's second sweep, The toolchain that formats or
    lints
    at commands/setup.md:148, already reads "the manifests, task files and scripts this project
    actually runs — whatever the language" and keeps only what formats or lints, as FORMATTERS. That
    same read now harvests the whole of the SDLC's needs
    , and the sweep's heading widens with it. It is
    not the Step 4 Capabilities sweep at :138, which builds a different registry (mcp | cli | skill,
    tool availability) and keeps both its name and its purpose. The harvested values are offered as
    proposals a human confirms or corrects, one need at a time, so a Consumer running Python sees a
    proposal for test drawn from what was detected rather than an empty prompt. This keeps a wrong value
    from being the path of least resistance; it does not stop a deliberate one.

  17. Every node that resolves a command carries the need-not-a-tool rule inline. The sentence lives
    in each prompt that reads the sdlc_needs block, not only in the ADR of criterion 12. The root
    AGENTS.md states the reason under its quality bar: a rule that lives only in an AGENTS.md is
    invisible at run time, and every prompt that must honour a rule carries it inline. AGENTS.md:57
    already carried this rule for formatter exclusions and the plugin broke it in five places, which is
    the evidence that a document-only home does not hold. A reader finds the sentence in the prompt.

  18. CONTEXT.md gains an entry for sdlc_needs, with the forms that lose named. The entry says
    what the block holds, that a key names a need and never a tool, and that a key with no reader is
    intended rather than a gap. Its _Avoid_ line names commands (the bare word is already forbidden at
    CONTEXT.md:241, where a Claude Code slash command claims it and an Archon workflow command template
    claims it again), toolchain, capabilities (taken by System-skill at CONTEXT.md:38 for a
    team-provided capability) and lifecycle_needs. This criterion exists because the first draft of
    this ticket named the block commands, breaking a rule CONTEXT.md already stated
    — the same
    failure criterion 17 was written against, one layer up.

  19. SDLC becomes this plugin's term, declared once, and "AI development lifecycle" becomes its
    gloss.
    The acronym appears zero times in the plugin today, while "AI development lifecycle"
    appears at CONTEXT.md:3, README.md:3, AGENTS.md:7 and AGENTS.md:47. Adopting an acronym for a
    concept the plugin already names another way is synonym drift unless it is managed, which is what
    CONTEXT.md exists to stop. So CONTEXT.md gains an entry for SDLC, expanded, naming the article
    of criterion 12 as its source and its six phases where they earn their place; it states which of the
    two is the term and which is the gloss; and the four sites above are made consistent with that ruling
    in the same commit. A reader cannot come away thinking they are two different things.

  20. coverage is the ninth key, and the number stays outside the block. Ruled by the maintainer on
    2026-09-03 19:22, option (b) of did-not-decide item 8. sdlc_needs.coverage names the need that produces a
    coverage figure; build.coverage_threshold stays where it is, because it is a number and not a need, and
    § Out of scope still holds for it. coverage-gate (unic-dlc-qa.yaml:120) and verification step 3
    (unic-dlc-build.yaml:410) resolve sdlc_needs.coverage and nothing else once criterion 4 removes the
    literal; neither appends a flag of its own to sdlc_needs.test or to any other declared command. A null
    coverage, or a declared one that cannot run, is unresolved under criterion 7. The threshold decides pass
    against fail; whether the node reports at all is item 9's ruling, not this criterion's. The ADR of
    criterion 12 records why the key exists: without it both nodes hold a threshold and nothing to execute.
    Criterion 2's list of keys with no reader is unchanged, because this one has two.

Which criteria are not plugin work

Named here so nobody hunts for a change that is not there.

  • Criterion 11 is a scope statement, and this body satisfies it by saying so. There is nothing to
    build for it. What it does carry into the plugin is criterion 10's last sentence.
  • Criterion 14 is the maintainer's, inside DXP-DesignSystem, after the plugin PR ships. So is the
    second half of criterion 13, from claude plugin update onwards.

Out of scope

  • Making DXP-DesignSystem have CI. The Consumer's own missing pipeline, recorded on
    #373.
  • coverage_threshold moving. It is a number, not a command, so it stays outside the sdlc_needs
    block. Nothing changes about it and no criterion above covers it.
  • slopcheck. It reads package.json and queries the npm registry, so it is JavaScript-only by
    construction, but it self-skips honestly at unic-dlc-build.yaml:106 and no criterion touches it.
  • unic-dlc-explore.yaml. It runs no build, lint, type-check or test command; its Bash use is
    git-shaped. Its package.json and pnpm-workspace.yaml read at :101 is the same class of problem and
    is not fixed here.
  • Running a dependency upgrade as any part of this. Archon is held at 0.7.0 until phase 1 ships its
    first stable release.

What this did not decide

  1. Whether a declared command is the right command. RULED 2026-09-03 by the maintainer: this is
    the Consumer's problem, not the plugin's.
    Criterion 16 reduces the chance at declaration time and
    criterion 7 reports a zero-count pass as suspicious. Past that, a Consumer that deliberately sets
    sdlc_needs.test to a no-op passes forever, and nothing detects a semantically wrong command. That is
    out of scope by decision, not by omission
    — a tenant who games their own gate is not an adversary a
    Harness can defend against, and trying would make the plugin judge a tenant's toolchain, which is the
    thing it refuses to name in the first place. Do not reopen this as a defect; it is a stated ceiling.
  2. Whether lint ever gains a reader. RE-FRAMED 2026-09-03 by the maintainer: not a gap. A key
    in this block names a need of software development that a Consumer may have, not a command this
    plugin must run. lint having no reader today is the design working: the block declares what the
    project can do, and a node reaches for whichever need it has at run time. A key with no reader is
    exactly as intended as a key with three. Do not add a lint-running node to close this.
  3. What an absent unresolved means outside the floor. Beyond test at the two gates, a node
    deciding it does not need a check reports nothing, and a reader cannot tell that from a node that
    never considered it. Accepted as the price of discretion; named here so nobody reads silence as
    coverage.
  4. What catches a node added later without the inline rule. Criterion 17 puts the sentence in every
    prompt that resolves a command today, so the rule is visible where the work happens. Nothing checks
    that the next node to read the sdlc_needs block carries it, and this repository deliberately does not
    grep agent prose to find out. Between two hands, a missing sentence surfaces on a read, or not at all.
  5. Whether .archon/workflows/*.yaml belongs in GUARDED. Today a PR changing only a Box merges
    with no bump and no changelog entry. Criterion 13 works around it because setup.md is guarded. The
    question is a separate ticket if the answer is yes.
  6. Whether a slice's test_command may be narrow at all. That is
    #448, and criterion 15 only keeps the two
    surfaces apart rather than answering it.
  7. What coverage-gate and verification step 3 run once the literal is gone RULED 2026-09-03 19:22 by
    the maintainer: option (b), a ninth key coverage. Criterion 1 amended, criterion 20 added; the text below
    stays as the record of the two options.
    (found 2026-09-03 by
    DLC-430-grilling, verified by the orchestrator).
    unic-dlc-qa.yaml:134 and unic-dlc-build.yaml:410 say "run coverage" and today know what to run only
    through the literal criterion 4 removes. Criterion 1 fixes the block at eight keys with no coverage, and
    § Out of scope keeps coverage_threshold outside the block. So after the edit both nodes hold a threshold
    and nothing to execute; an implementer holding the criteria alone adds a ninth key (breaks 1) or keeps the
    literal (breaks 4). Two ways out: (a) read the coverage figure out of what sdlc_needs.test reported,
    with a null threshold or a null test reported as unresolved, and never append a flag of the Box's own to
    a project's command — no new key, and a Consumer whose test emits no coverage gets unresolved whenever a
    threshold is set, which is honest; (b) a ninth key coverage, amending criterion 1. The orchestrator
    recommends (a) with its cost written into the ADR of criterion 12. Whichever is ruled becomes a criterion.
  8. How criteria 7 and 8 read together at a node that exists to run one need (same source, same date).
    "A node that abstains reports nothing" and "unresolved covers the command not being declared" hold together
    only if the distinction is wanting a need, not declaring it: the e2e node always wants e2e, so
    sdlc_needs.e2e: null there is unresolved, never a skip; "reports nothing" covers only a node that never
    reached for the check. Consequence: skip leaves the result enum of e2e (unic-dlc-qa.yaml:112) and
    coverage-gate (:145). Decided by reading, recorded here so the implementer does not keep skip and
    satisfy both criteria by changing nothing.
  9. Why run 2's goals-check returned four acceptance-criteria failures. The register's correction
    established that the suite really ran and really passed, so the missing install does not explain those
    four. Open, not answered.

Activity

  1. added
    bugSomething isn't working
    needs-specsEnough info from reporter; ready to write a spec
    p2Medium priority
    on Aug 26, 2026
  2. orioltf commented on Sep 1, 2026

    @orioltf
    MemberAuthor

    Second instance, and it now extends past pr-review — 2026-09-01

    Run 2 of the full chain in DXP-DesignSystem hit this again, and it is worse than "the review Box cannot verify claims".

    It also applies to the build leg's own review nodes. implement-review-precheck and the unic-dlc-pr-review rounds all ran in Archon worktrees with no node_modules. Round 1 stated its own limitation rather than bluffing, which is the right behaviour:

    "node_modules is absent in this worktree, so neither axis could execute tailwind-merge: verify the exact theme-key names against a regenerated snapshot rather than trusting the shape above."

    But the same run produced the failure this issue predicts. verification returned PASSED — 17 tests, 0 failed — while goals-check returned passed: False with four acceptance-criteria failures, minutes apart in the same run. One of the four was a measured accessibility defect: aria-disabled="false" reaching the DOM and a consumer's handler firing on a disabled card.

    The only exit codes the run has came from a human, who checked out the branch into the registered clone and ran a frozen-lockfile install, build, typecheck, lint and test by hand. All green. That check is exactly what no node in the chain could perform.

    Why it belongs on this issue rather than a new one

    The cause is unchanged — git worktree add copies tracked files and a pnpm workspace's dependencies are not tracked. What has changed is the blast radius: every review node in the lifecycle, not one Box. Any criteria written here should cover all of them.

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

  3. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    How to start this session

    STALE as advice since 2026-09-03 18:35. This was the grilling opener; the grilling is done and its decisions are in the body. The implementation opener is the newest "How to start this session" comment on this ticket. Read this one for its measurements only.

    Written 2026-09-03 by wayfinder-orchestrator-4. This is a grilling session 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

    The maintainer types /grill-with-docs. Not /grilling on its own: .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
    alone with nowhere durable for the decisions to land. grill-with-docs composes domain-modeling, which is what
    gives a settled decision a home.

    Do not invoke /implement or /tdd. Nothing is being built here.

    Read order

    1. This ticket's body, then its 2026-09-01 comment. The comment widens the finding past pr-review and is
      newer than the body it corrects.
    2. docs/research/2026-08-31-dlc-run-2-findings.md, row 41 and the § F4 "Amended rather than filed" entry
      for bug(unic-archon-dlc): the config maps commands to nodes and the Boxes name tools, so a check runs by luck or not at all #430. Row 41 carries the measurement; § F4 carries what run 2 added to it.
    3. The three Box files that run a command, in this order —
      apps/claude-code/unic-archon-dlc/.archon/workflows/unic-dlc-build.yaml (the bootstrap, run-build and
      verification nodes), unic-dlc-pr-review.yaml, unic-dlc-qa.yaml (the e2e and coverage-gate nodes).
      unic-dlc-explore.yaml runs no build, lint, type-check or test command — its Bash use is git-shaped — so it is out of scope.
    4. Issue wayfinder: unic-archon-dlc is prose, and proven at a Consumer #373's body, § THE FOCUS — the class table that makes this an instrument rather than a variable.
    5. apps/claude-code/unic-archon-dlc/AGENTS.md and the root AGENTS.md § "Acceptance criteria are prose",
      before writing a single criterion.

    Correction to the ticket, before the first round

    The title says unic-dlc-pr-review. The defect is in three Boxes, and they fail three different ways. This
    is measured or read, not inferred, and the grilling should open on it rather than discover it:

    Box What it does with no node_modules Evidence
    unic-dlc-pr-review Says it could not verify. Honest. Run 2 round 1, quoted in this ticket's 2026-09-01 comment
    unic-dlc-build verification reported PASSED while goals-check returned four AC failures minutes later. False positive. Run 2, register § F4
    unic-dlc-qa Its e2e node maps any non-zero exit to result: "fail", and a missing binary is non-zero. False negative — a broken install reads as a broken test suite. Read from the prompt in unic-dlc-qa.yaml; unmeasured — no run of /qa is on record in this stream

    One cause, three verdicts, one of them honest. A fix decided for pr-review alone leaves run 3's build leg
    reporting green on nothing.

    Run this measurement before round 1

    The ticket rejects its own option 1 on the premise that an install costs "minutes and a lot of disk". Nobody
    has measured that, and options 1 and 2 collapse into each other if it is false.

    The check: create a scratch worktree of the Consumer's clone, time pnpm install --frozen-lockfile
    in it, and measure the disk it actually consumes. What is known already: the store is at
    ~/Library/pnpm/store/v11 and holds 498M, and files under the Consumer's node_modules/.pnpm have a hard-link
    count of 1, so pnpm is not hard-linking on this machine. On APFS that most likely means copy-on-write
    clones, which would make an install fast and nearly free on disk. Most likely is not measured. Take the
    number into the room.

    The one trap that costs an hour

    A Box-only fix does not reach the Consumer, and nothing in this repository says so.

    Two mechanisms, both verified 2026-09-03:

    • .archon/workflows/*.yaml is not in GUARDED in packages/release-tools/scripts/lib/changelog-gate.mjs
      — that list holds scripts/*.mjs, commands/*.md, both .claude-plugin JSON files, CLAUDE.md and
      README.md. So a PR changing only a Box merges green with no version bump and no changelog entry.
    • DXP-DesignSystem's .claude/settings.json sets "autoUpdate": false. The Consumer pulls nothing on its
      own, and /unic-archon-dlc:setup is what copies Boxes into .archon/workflows/.

    So a Box fix reaches run 3 only after a deliberate version bump here, then claude plugin update, then a
    /unic-archon-dlc:setup re-run at the Consumer. A criterion that ends at "the Box installs dependencies" is
    satisfied by a change run 3 never sees.
    Decide in the room whether a criterion names the delivery, and whether
    .archon/workflows/ belongs in GUARDED at all — that second question is a separate ticket if the answer is
    yes, not scope creep into this one.

    The questions the ticket does not ask

    Its three options are a shape menu. These are the decisions underneath, and two competent implementers answer
    at least three of them differently.

    1. Which node installs, and how often. One Archon worktree serves a whole run, and the build Box's RED and
      GREEN phases are fresh contexts in that same worktree — the baton is committed artefacts, not session
      memory. So one install at bootstrap covers everything. Nothing in the ticket says this, and "before the
      verification node" reads as an install inside the per-slice loop, which would pay it once per phase.
    2. How a Box knows it is a JavaScript repository at all. The Boxes are language-agnostic by design.
      pnpm install in a Python repository is wrong. Lock-file sniff, or a config key, or the capability registry
      /setup already builds?
    3. Where the command's name lives. Hard-coded, or a config key beside build.e2e_command, qa.e2e_command
      and build.coverage_threshold? ADR-0018 puts templates in config; the register's finding 40 says a gate
      check must not be a config value. Those are not the same rule, and the difference needs saying out loud
      rather than assuming.
    4. What a failed install does. Fail the run, or fall through to the honest summary? Whichever is chosen,
      the summary must keep distinguishing "verified" from "could not verify" — the ticket is right that this is
      the load-bearing part, and it survives every option.
    5. Whether /qa's false negative is the same fix or a second one. Its e2e node conflates "the command
      failed" with "the tests failed". An install fixes the symptom; the conflation stays, and the next missing
      binary reads as a red suite again.

    The option this moment does not have

    Option 3 — "the summary line is the permanent shape, and the human treats an unverified claim as unverified" —
    is a defensible permanent answer and it is not available for run 3. Run 3 asks whether mechanisms reach the
    implementer where documents did not. A review leg that cannot execute a check is a broken instrument, not a
    result, and #373's FOCUS table classes this ticket as an instrument for exactly that reason. Say so in round 1
    so the room is choosing between two shapes, not three.

    What this grilling must not do

    Before you write the criteria, do these four reads

    From the root AGENTS.md, and #441 proved last night that six grilling rounds do not retire them:

    • Read them as one set, hunting the gap between two that an implementer would fill with a defensible-sounding
      decision.
    • Turn the diagnosis on the cure. This ticket says the review cannot check claims. Ask what the fix still
      cannot check.
    • Ask which criteria are satisfied by changing nothing. Name them in the ticket rather than leaving someone
      to hunt for work that is not there.
    • Close by listing what you did not decide. "Either is acceptable" and "whichever fits" are where an
      unanswered question hides.

    And one adopted 2026-09-03, from #441: the four reads run twice — once on the criteria here, and again 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 it satisfied, which no reading of the ticket could reach.

    On landing

    The grilling ends with the criteria in this body, a "what this did not decide" section, and the label still
    needs-specs. The maintainer approves the criteria; ready-for-agent follows, and the implementation opener is
    written at dispatch, not now.

    Report back

    BEFORE YOU FINISH, AND WHENEVER YOU LEARN SOMETHING THAT WOULD HAVE CHANGED THIS PROMPT, SendMessage to
    the live orchestrator seat (wayfinder-orchestrator-5 as of 2026-09-03 18:05; seat 4 is spent) — confirm the name with ListAgents first, and if no orchestrator seat is live,
    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. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    Opener correction — two errors in the opener above, and the ticket's premise is measured false

    Written 2026-09-03 by wayfinder-orchestrator-4, after DLC-430-grilling reported before round 1. Everything
    here is verified independently from the orchestrator seat, not taken on the session's word.

    1. Read-order item 4 points at a section that does not exist. #373's body has five headings — Destination,
    Notes, Decisions so far, Not yet specified, Out of scope. There is no § THE FOCUS, and the
    treatment/instrument/confound class table is not in that body at all. It lives in the orchestrator's handoff
    file, ~/Desktop/orchestrator-handoff.md, under # THE FOCUS — what to do next, and in what order (line 577).
    Read it there. My citation was an inference from a file I hold, dressed as a fact about a file you would open.

    2. The ticket's premise is measured false, and the finding underneath it is sharper, not softer. The session
    measured all sixteen Archon worktrees for DXP-DesignSystem on this machine. Twelve have node_modules; four
    do not.
    I re-ran the check and got the same split. Every one that has it was created 5–13 minutes after its
    worktree, mid-run — and no Box instructs any node to install, so a node created it on its own initiative.

    So the defect is not "the review cannot run checks". It is "whether a check can run is a coin flip, and no
    node reports which way it landed"
    . Round 1 opens there. That reframing kills any criterion satisfied by
    observing a green run, because a green run already happens by luck.

    3. The install cost premise is dead. pnpm install --frozen-lockfile in a scratch worktree of the Consumer,
    warm store, APFS: 4.4 s wall clock across two runs, 637 packages, 0 downloaded, and 16 MB of real
    free-space delta against the 375M du reports — APFS clones the store, which is why the hard-link count of 1
    does not mean copies. Options 1 and 2 have collapsed into one. The room chooses between installing and not.

    4. Correction to the register, already applied. docs/research/2026-08-31-dlc-run-2-findings.md said run 2's
    verification PASSED while goals-check returned four AC failures, and attributed that to a missing install.
    The observation is true; the attribution is wrong. That worktree had node_modules — born one second after
    run-build ran a playwright install — and verification's own tool_called payload at 17:56:22 UTC is pnpm test 2>&1 | tail -60, verdict 17 tests, 17 passed, turbo 0 cached. The suite really ran and really passed.
    Row 41 and the § F4 entry now say so. goals-check's four failures are about acceptance criteria, not exit
    codes, and this finding does not explain them — treat that as open, not answered.

    What made the original reading look sound, and it is worth carrying: Archon's SQLite stores UTC while stat
    prints local time.
    Two hours on this machine, and it turned a mid-run install into a post-run human one.
    Memory reference_archon_db_utc_stat_local.

    What does not change. The three-Box scope, and the trap. A Box-only fix still reaches no Consumer without a
    deliberate bump, claude plugin update and a /unic-archon-dlc:setup re-run. Option 3 is still unavailable for
    run 3. The five questions under the option menu all still need answering, and question 1 — which node installs,
    and how often — is now the load-bearing one, because the answer today is "whichever node feels like it".

  5. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    Second correction — the three-Box table was wrong, and the ticket splits in two

    Written 2026-09-03 by wayfinder-orchestrator-4, from DLC-430-grilling's pre-round-1 report, verified independently here before posting.

    unic-dlc-pr-review instructs no command at all. grep -cE "pnpm |lint|typecheck|type-check|install|node_modules" over that Box returns 0, and its Method — code-review — runs nothing either. It is a diff read on two axes. So run 2's honest "node_modules is absent, so neither axis could execute" was a sub-agent volunteering a check nobody asked it for.

    That splits this ticket in two, and my opener's table collapsed them into one:

    • a capability gap — the dependencies are not there, non-deterministically
    • an instruction gap — no node asks for the check

    An install alone changes nothing in pr-review, because nothing there wants to run. The room decides two things per Box, not one.

    The /qa row is unreachable on this Consumer, not merely unmeasured. git show origin/develop:.archon/unic-dlc.config.yaml in DXP-DesignSystem has build.e2e_command, build.coverage_threshold, qa.e2e_command and qa.coverage_threshold all null (lines 66, 67, 98, 99). /qa's e2e node takes the null branch, prints SKIPPED non-blocking, and /qa merges on UAT alone with zero test evidence. A third failure mode nobody had named: a configured hole, off by default.

    Where a command is actually instructed — four sites, in two Boxes:

    unic-dlc-build.yaml:403 verification runs e2e_command ?? test_command ?? pnpm test — always runs something, the chain ends in a literal
    unic-dlc-build.yaml:294 the implement prompt: "Run typechecking and the single test file"
    unic-dlc-qa.yaml:104 e2e runs e2e_command; null → skip
    unic-dlc-qa.yaml:134 coverage-gate runs coverage; threshold null → skip

    So lint is instructed nowhere, and typecheck exactly once — inside a prompt, not as a node with a verdict. This ticket's title says "build, lint, type or test claims"; only test and coverage are ever asked for.

    A fourth shape, which the ticket does not carry and which is cheaper than its three. The config comment above those nulls reads "No test runner wired at the repo root yet. Both Boxes skip their gate and say so." That is now stale. origin/develop's root package.json carries test: turbo run test -- --run, lint: turbo run lint and check-types: turbo run check-types, and PR 5843 made root pnpm test run 51 tests across checks and checks-dom. The hole is not a missing capability — it is four config values that were true when written and stopped being true this week.

    So: set the values, and give a Box a reason to notice when its config says a capability is absent that the repository now has. The second half is the durable part; the first is a one-line edit.

    Unchanged from the opener: the trap (a Box-only fix reaches no Consumer without a bump, claude plugin update and a /setup re-run) and that option 3 is unavailable for run 3.

    Map position, new today. This ticket is a child of #456, the run-3 map, labelled wayfinder:grilling, and it blocks #457. Its Azure DevOps mirror is 43034, 5 points, under Feature 42975 — so this work counts for the client, who has no GitHub access. The class rule the opener sent you to the handoff file for is now in #456's Notes.

  6. changed the title [-]unic-dlc-pr-review cannot verify build, lint, type or test claims — no node_modules in the Archon worktree[/-] [+]bug(unic-archon-dlc): the config maps commands to nodes and the Boxes name tools, so a check runs by luck or not at all[/+] on Sep 3, 2026
  7. added
    ready-for-agentFully specified, ready for an AFK agent
    and removed
    needs-specsEnough info from reporter; ready to write a spec
    on Sep 3, 2026
  8. 4 remaining items

  9. added a commit that references this issue on Sep 3, 2026
  10. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    How to start this session

    Written 2026-09-03 18:30 by wayfinder-orchestrator-5, revised in place 18:55 after a first implementation
    attempt was discarded, report clause re-pointed to seat 6 at 19:05, item-8 ruling folded in at 19:25, DLC-430's five corrections at 19:35, criteria 8/9 rewording and the order ruling at 20:45 on 2026-09-04 (its four learnings are folded in below, marked ★). This is the implementation opener.
    The maintainer's plan is one fresh session that implements #430 and then #439, after #439's grilling (order ruled "a" on
    2026-09-04: #430 first; #439 left run 3's map the same evening and edits evidence AFTER you, so criteria 8 and 9 were
    reworded around the verdict, read them fresh); read
    § What this did not decide items 8 and 9 in the body — item 8 was RULED at 19:22 (option b, a ninth key coverage,
    criterion 20).
    The grilling is done: the body carries twenty approved criteria and the maintainer's three rulings. The three earlier
    "How to start" comments on this ticket (09:31, 09:42, 12:42) are stale as advice — read them for the
    measurements they record, follow none of their steps.

    What it produces, and which skill

    One pull request against develop in unic-agents-plugins that satisfies the eighteen plugin criteria (counted as entries in the list below),
    plus one comment on this ticket handing the maintainer his two hand-steps (below). No YAML runs in the
    Consumer from your session; nothing in DXP-DesignSystem changes by your hand.

    Enter with /wayfinder 456 430, typed by the maintainer. It claims the ticket by assigning it, which
    nothing else does. Check the assignee first — if it is already set, report "already claimed" and go
    on. Then leave the skill at its step 4 and do not close this issue: this stream implements a bug under
    its own number, the maintainer merges and closes, and #456's Decisions-so-far line is the orchestrator's
    to write at close. Said again under § On landing.

    Skills: /writing-for-agents for every prompt line you touch (a Box node is a prompt), /domain-modeling
    for the CONTEXT.md entries and the ADR. Not /implement — it routes to /tdd, and this plugin
    ships no code and no tests (decisions 3 and 11; root AGENTS.md names a module-plus-test a defect).
    Not /grilling — done. /code-review before the PR leaves draft (pipeline below).

    The criteria have two homes — read this before you read them

    Eighteen entries are yours: 1–10, 12, 13 (first half), 15–20. Count them; two earlier versions of this line undercounted. The rest:

    Criterion Whose What it is
    11 nobody's a scope statement the body satisfies by saying it; it feeds criterion 10's last sentence and nothing else
    13, second half the maintainer's, inside DXP-DesignSystem claude plugin update, then /unic-archon-dlc:setup (reports, changes nothing), then /unic-archon-dlc:setup reconfigure
    14 the maintainer's, same place real values for sdlc_needs.install and sdlc_needs.test in the Consumer's config

    A worker reading straight through attempts 14 and cannot: the Consumer's config is tenant-owned and
    your session is rooted in the plugin repo. What you owe instead is one comment on this ticket after
    the PR opens, listing those steps with the version they need and where the Consumer's two values come
    from (its own root manifest's scripts and its package manager's install command) — naming no value.
    The plugin names no tool, and neither does a comment written on its behalf.

    Two more criteria are satisfied by changing almost nothing, so do not hunt for work: criterion 15's
    "that surface is untouched" half (the per-slice test_command in issues.json, read at
    unic-dlc-build.yaml:279 and :296, stays exactly as it is), and criterion 2 is comment text inside
    the template.

    Read order

    1. This ticket's body, in full, as one set. Then the 09:42 and 12:42 comments for facts only:
      the 12-of-16 worktree split, the 4.4 s install cost, and the table of the four sites where a Box
      instructs a command today.
    2. #456 § Notes — the class rule. This ticket
      is an instrument: it changes whether a check's outcome can be read, never what the chain produces.
      A change that makes a node run a check it did not run before, outside the test floor at the two
      gates, has left the class.
    3. apps/claude-code/unic-archon-dlc/AGENTS.md § Plugin doctrines: "A Box states WHICH repository and
      never HOW" (rules stated inline, no tool names), "No code at all", "A Plugin ADR takes its form…",
      and the evidence-gate bullet. CONTEXT.md entries config.yaml, Evidence gate, Evidence
      set
      , System-skill (:38, it owns capabilities) and Claude Code slash command (:241, it
      owns commands).
    4. The nodes you will edit, in this order: the three bootstrap nodes (unic-dlc-build.yaml:28–74,
      unic-dlc-qa.yaml:21–74, unic-dlc-pr-review.yaml:26–77 — all allowed_tools: [Read, Bash, Glob],
      all "Emit ONLY the structured object"); verification (build:391); evidence (build:480–560, a
      script: node, read its comments — one of them says never to write a placeholder node id anywhere in
      that body); e2e (qa:89), coverage-gate (qa:120), merge (qa:334, whose when: at :337
      is the gate criterion 9 names); report (build:561) and post (pr-review:560), which are where
      criterion 10's block lands.
    5. commands/setup.md Step 4 (:134–163, the two sweeps criterion 16 tells apart) and Step 6 § The
      config (:253–294, the template criterion 1 changes).
    6. docs/adr/README.md (form, Status line, inline revision — the dated > **Amended** blockquote
      convention is retired since docs(unic-archon-dlc): ADR-0020 states superseded claims below three amendment blocks #452; do not add one). Then the ADRs this change revises: ADR-0034 (the
      evidence gate reads a passed boolean and a failures array; criterion 8 adds a third state),
      ADR-0025 (/qa's e2e_command resolution), ADR-0023 §5 (why evidence inlines and imports nothing),
      ADR-0026 (/pr-review runs nothing by instruction — criterion 11's home in the ADRs), ADR-0019 and
      ADR-0036 (what /setup writes and when it reports). Revise inline where a detail changed; leave the
      decision alone where it did not.
    7. Root AGENTS.md § "Acceptance criteria are prose" and § "The quality bar for a prose Box".
    8. docs/research/2026-08-31-dlc-run-2-findings.md row 41 — the corrected finding under this ticket.

    The decision the ticket does not make

    Four places where two competent implementers diverge. Decide each before editing, and write the
    decision into the ADR, not only into the YAML.

    1. Where each Box's test outcome comes from in /qa. Criterion 9 says /qa's merge cannot
      advance without a test outcome. Today /qa runs e2e and coverage-gate and no test at all,
      and merge's when: reads != 'fail' on both, which a third state unresolved passes today. Either
      the e2e node grows a test run, or a test node is added beside it. Recommendation: a node of its
      own, so each need has one outcome field; and the when: on the floor reads == 'pass' for test
      while != 'fail' stays for e2e and coverage — because of the next item.
    2. The gap between criteria 8 and 9. 8 says unresolved holds a gate; 9 says only test is
      mandatory. (Both reworded 2026-09-04: evidence EMITS a three-state verdict, printed to stdout as JSON because a
      script: node's output_format is ignored and only stdout resolves as $evidence.output.*; it does not
      "withhold". You change the verification/goals-check sentence about what evidence does for the third state;
      you do NOT touch its evidence_policy clause or the evidence node's comment block, both bug(unic-archon-dlc): open-pr precedes its gate, and a config-value gate has no safe middle #439's.) Read together: a node that abstains from a non-floor need reports nothing (did-not-decide
      item 3 accepts that), a node that tries a declared need and cannot run it reports unresolved, and
      only a test unresolved holds the gate. State that reading in the ADR. Without it, one implementer
      holds the merge on an unrunnable e2e and another does not, and both pass the criteria.
    3. What bootstrap emits for the install, and who reads it. Criterion 6 says bootstrap "says what
      it did"; criterion 10 says any install report reaches a summary as a visible block. bootstrap prints
      nothing durable — it emits a structured object — so the report must be a schema field with a
      named downstream reader that writes it into the repo-relative Session dir: report in /build,
      the summary post writes in /pr-review. /qa has no such node. Its e2e.summary and
      coverage-gate.summary fields have no reader at all (grep -o '\$e2e\.output\.[a-z_]*' unic-dlc-qa.yaml
      returns result only), and uat-gate's approval message points the human at console scrollback.
      Decide where /qa's block lives — the uat-prep checklist is the one surface a human reads there —
      and give every field you add a reader in the same commit (memory feedback_reader_needs_writer).
    4. What verification runs now that the fallback chain is gone. Today: e2e ?? test ?? pnpm test.
      After: test always (it is the floor evidence reads), e2e in addition when declared, each with its
      own three-state outcome. Do not keep "prefer e2e over test" — it made test optional, which criterion 9
      forbids.

    Other traps

    • evidence must PRINT its verdict as JSON, not only write the file: measured 2026-09-04 in a throwaway repo,
      a script: node's output_format: is ignored and its output is raw stdout. Whatever field criterion 8 adds to
      evidence's output exists downstream only if console.log emits it.

    • ★ No Box uses a nested node-output reference (grep -ohE '\$[a-z][a-z-]*\.output\.[a-z_]+(\.[a-z_]+)+' *.yaml
      returns nothing across the four). $bootstrap.output.sdlc_needs.test would be the first, on the load-bearing
      path, against a resolver nobody has proven. Pass the whole block and let each prompt read its own key — which is
      what criterion 3 asks for anyway.

    • ★ uat-prep has no Write tool (unic-dlc-qa.yaml:157, [Read, Bash, Glob]). Criterion 10's durable block
      in /qa needs the tool added, not only a file named. Say why in the node comment.

    • ★ skip leaves the result enum of e2e (:112) and coverage-gate (:145): body item 9.

    • ★ Coverage now has a key to run: body item 8 was ruled (b) at 19:22, criterion 20. coverage-gate and
      verification step 3 resolve sdlc_needs.coverage; build.coverage_threshold stays where it is. Nine keys in the
      template, not eight; criterion 2's no-reader list is unchanged.

    • test_command is two things (criterion 15). Per-slice, written by /tickets at commands/tickets.md:165
      and read by RED/GREEN, stays. Only bootstrap's project-wide test_command becomes sdlc_needs.test.
      Grep both before and after; the collision is why this was hard to see.

    • Two artifacts directories. $ARTIFACTS_DIR is outside the repo and gitignored; <artifacts_dir>/<slug>/
      is repo-relative and committed. evidence writes both on purpose. Do not touch that, and put nothing
      a reviewer must read under $ARTIFACTS_DIR. Memory reference_archon_artifacts_dir.

    • Zero pnpm in the three Box files after the edit (criterion 4, corrected 19:35). slopcheck holds npm at
      build:84 and :130, not pnpm; leave those. A dated evidence citation may name a tool; the changelog may say
      what literal was removed; no prompt, ADR body or CONTEXT.md entry may name one. unic-dlc-explore.yaml:101 is
      out of scope — leave it.

    • The evidence script node stays a script node and inlines its logic. No module, no import from the
      plugin. Its comment block says the DAG loader reads every $<node>.output token as an edge, comments
      included — do not write one you do not mean.

    • Criteria 1, 5 and 8 were amended today (four-reads pass, then DLC-430's hold read): README.md:186–187,
      docs/boxes/unic-dlc-qa.md:26–27, :78–79 and commands/setup.md:273 describe the keys you retire; README.md's
      config table gains nine sdlc_needs rows (setup.md:285 forbids proposing a key that table omits); plugin
      AGENTS.md:91's evidence-gate bullet loses "only when both are true". All in this PR.

    • Version: minor, never major. Removing config keys is breaking; on a 0.x plugin that is
      pnpm --filter unic-archon-dlc bump minor → 0.28.0, with a ### Breaking changelog entry that names
      the removed keys and says an existing Consumer needs /unic-archon-dlc:setup reconfigure. Header
      format ## [X.Y.Z] — YYYY-MM-DD. commands/setup.md and README.md are both in GUARDED, so CI
      refuses the PR without the entry.

    • The ADR is referenced by slug, never by number, until it merges; today's highest is 0036, and an
      in-flight ticket may take 0037 first.

    • Two CONTEXT.md entries, not one paragraph (criteria 18, 19): sdlc_needs (nine keys) with its _Avoid_
      line (commands, toolchain, capabilities, lifecycle_needs), and SDLC naming its source, its six
      phases where they earn a place, and which of SDLC / "AI development lifecycle" is the term. Then
      CONTEXT.md:3, README.md:3, AGENTS.md:7 and AGENTS.md:47 made consistent in the same commit.

    • Work in a worktree outside the clone — ../uap-wt-430 — never the shared clone; Biome ignores
      **/.claude, so a worktree under .claude/worktrees/ fails pnpm check. Absolute paths in every
      Bash call (cd does not persist here); never a foreground sleep; git rev-list --count origin/develop..HEAD before every push; git push -u origin <branch> on the first push.

    • pnpm format and pnpm ci:check exist only at the repo root, judged by exit code. Prettier repads
      a whole Markdown table on a one-cell edit — re-run format before committing README changes.

    The bar that proves it

    The false pass: three Box YAMLs edited, archon workflow list lists them, pnpm ci:check green,
    grep pnpm returns nothing in the three Box files. None of that ran a node. Every command defect of this plugin's
    0.22.0 was invisible here and visible on the first Consumer run.

    The real bar, before the draft flips: one Box run in DXP-DesignSystem on the edited Box against a
    config with no sdlc_needs block, and read in the run's own artefacts that bootstrap reported
    "sdlc_needs.install is not declared" and the downstream gate held on unresolved. Run unic-dlc-pr-review
    for this — /build opens a pull request as a side effect and /qa merges one. Three rules from the
    Consumer's docs/agents/unic-archon-dlc.md § Three Archon defects that land here, cited not restated:
    Archon runs the Box from the invocation directory's working tree, so copy the edited Box AND a config
    that sets gates.pr-review: hitl into the registered clone uncommitted, dispatch from there with
    --from, shasum the worktree's Box against your branch before the gate, and restore the clone
    after; archon workflow status before touching any worktree; harvest <artifacts_dir>/<slug>/ before
    archon complete <branch> --force, and abandon, never reject — review-gate has no on_reject.
    The Consumer main clone sits on verify/43004-build; read it on origin/develop. If you find a cheaper
    proof that still runs a node, propose it to the orchestrator first; "no run" is not a proposal.

    On landing

    • Bump minor, changelog ### Breaking, PR to develop as draft. /code-review with this ticket as
      the Spec axis input, then one summary comment on the PR (per-axis counts, fixes with commit refs,
      refutations, and a named "what both axes agreed on" section). Flip the draft only after gh pr checks
      is green by exit code, and only if you drafted it yourself.
    • Copilot reviews on un-draft and on every push. Read every review body to the end, not the thread
      list: a review can carry a finding under Suppressed comments (n) with zero inline comments.
      gh api repos/unic/unic-agents-plugins/pulls/<n>/reviews --jq '.[]|select(.user.login|test("copilot"))|.body'.
      Check .commit_id. Cap three rounds, judged by what a round produced; then post what remains and hand
      over. After each round's fixes, re-read the fixes as a set: did they multiply the surface they reduce?
    • Iteration 2 (reconcile) is mandatory for any finding you mark fixed. Fixing a finding closes its
      thread in the same pass, with the commit ref.
    • Before handover, after the last commit, re-read the PR description against the final diff and correct
      every claim a later commit falsified.
    • Then post the maintainer's hand-steps comment on this ticket (see § two homes), and do not close this
      issue
      : the maintainer merges, moves the state label to resolved (nothing in the merge path does), and
      the orchestrator writes wayfinder: run 3 — do mechanisms carry the knowledge where documents did not? #456's Decisions-so-far line and moves ADO
      43034 (13 points, title + link + points +
      state, never a body copy). Dispatch run 3, read both legs against sealed predictions, and write it up #457's blocker clears on merge, not on PR open.
    • The four reads run twice — once on the criteria (done in grilling), once on your diff with the
      unchanged lines around each edit in view. fix(unic-archon-dlc): /specs skips the grilling its config requires and reports halts that never fired #441 shipped a gate that could not fire because of an
      unchanged sentence three lines above the criterion that satisfied it. Memory
      feedback_four_reads_against_the_diff.

    Report back

    BEFORE YOU FINISH, AND WHENEVER YOU LEARN SOMETHING THAT WOULD HAVE CHANGED THIS PROMPT, SendMessage to
    wayfinder-orchestrator-6 — confirm the name with ListAgents first, and if no orchestrator seat is
    live, 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.

  11. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    Two criteria amended in the body today, 2026-09-03, by wayfinder-orchestrator-5, on the four-reads pass before dispatch. Both are marked inline with the date.

    • Criterion 5 gains the two documents that describe the retired keys and that no criterion named: README.md's config table rows for build.e2e_command / build.coverage_threshold, and docs/boxes/unic-dlc-qa.md's resolution line and config table. Same shape as Move the DLC's tracker contract from config into the repo docs #389's nine criteria stopping at four Box files.
    • Criterion 10 now says the visible block is durable, in a file under <artifacts_dir>/<slug>/, and that a console-only block does not satisfy it. Found while grilling bug(unic-archon-dlc): a review node produced thirteen findings and recorded them nowhere #438: /qa has no report node and its e2e / coverage-gate summaries have no DAG reader, so the criterion as written was satisfiable in scrollback and a green PR would have implemented that.

    Nothing else in the body changed. The implementation opener below was written against the amended body.

  12. assigned and unassigned on Sep 3, 2026
  13. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    Body amended 2026-09-03 19:22 by wayfinder-orchestrator-6, on the maintainer's ruling. Did-not-decide item 8 is ruled: option (b), a ninth key coverage. Three edits, all in the body:

    • Criterion 1 now says nine keys, with coverage last, and records that its first version said eight.
    • Criterion 20 is new: what coverage-gate and verification step 3 resolve, that build.coverage_threshold stays outside the block, and that a null or unrunnable coverage is unresolved under criterion 7.
    • Criterion 12's ADR sentence says eight of the nine keys come from the SDLC article and coverage from criterion 20.

    Item 8's text stays as the record of the two options. Item 9 is unchanged and criterion 20 defers to it on whether the node reports at all. The implementation opener (comment 5528586663) is edited in place to match.

  14. orioltf commented on Sep 3, 2026

    @orioltf
    MemberAuthor

    Body amended 2026-09-03 19:35 by wayfinder-orchestrator-6, from four contradictions DLC-430 found while reading under hold, each verified from the orchestrator seat on 0b74117:

    • Criterion 1: README.md § Configuration reference gains one row per sdlc_needs key. commands/setup.md:285 forbids asking for a key that table omits, so criterion 16 depended on rows nobody had named.
    • Criterion 4: the grep for pnpm across the three Box files returns nothing at all. slopcheck holds npm, not pnpm; "nothing outside slopcheck" described a survival that does not exist.
    • Criterion 5: third site, commands/setup.md:273, names both retired keys.
    • Criterion 8: plugin AGENTS.md:91, the evidence-gate doctrine bullet, says "only when both are true" and is revised in the same PR.

    The implementation opener (comment 5528586663) is edited in place to match, and its criteria count corrected: the list 1–10, 12, 13 (first half), 15–20 is eighteen entries, not sixteen.

  15. orioltf commented on Sep 4, 2026

    @orioltf
    MemberAuthor

    Body amended 2026-09-04 20:45 by wayfinder-orchestrator-6, on the maintainer's rulings in #439's grilling. Criteria 8 and 9 are reworded around the verdict evidence emits, because #439 makes evidence write always and stops open-pr on red with a node when:; "withhold" described a mechanism that will not exist. Intent unchanged: an unresolved need never reaches a pull request as green, and test is the floor. The sentence in verification's and goals-check's prompts about what evidence does is this ticket's to change for the third state, and #439's to change again for always-write. Order ruled: #430 first, #439 second (Q10 "a", the maintainer notes he may revisit as the grilling continues). The implementation opener (comment 5528586663) is edited in place to match. #439 left #457's blockers today and joined run 4; it no longer collides with #430 on class.

  16. self-assigned this
    on Sep 4, 2026
  17. orioltf commented on Sep 4, 2026

    @orioltf
    MemberAuthor

    Opener correction — the Consumer-run bar named a Box that cannot show half of it

    Supersedes one sentence of the implementation opener (comment 5528586663) § The bar that proves it, 2026-09-04 23:25, wayfinder-orchestrator-6. A session is running against the opener, so this is a superseding note, not an edit.

    The opener said: run unic-dlc-pr-review and read that bootstrap reported "sdlc_needs.install is not declared" and the downstream gate held on unresolved. /pr-review has no gate that reads a check outcome; criterion 8 says so. Found by DLC-430 (grep -n 'approval:\|when:' unic-dlc-pr-review.yaml returns three conditions, none on a check result).

    Ruled: the bar splits across two Boxes. pr-review proves the install report and criterion 10's block in the posted summary. /qa with gates.qa: hitl proves the new test node reports unresolved on a config with no sdlc_needs block and that uat-prep writes qa-checks.md with it; the run is abandoned at uat-gate, never rejected, because uat-gate's on_reject files agent-ready issues on the Consumer's tracker. The gate hold itself is not observed (merge's when: is never evaluated, and reaching it would need an open pull request); the PR's summary comment says so in those words. Harvest qa-checks.md before archon complete.

    Everything else in the opener stands.

  18. orioltf commented on Sep 4, 2026

    @orioltf
    MemberAuthor

    Your two steps, after the plugin PR ships

    The plugin half is PR #461, ready for review. Criterion 14 and the second half of criterion 13 are yours, inside DXP-DesignSystem, and nothing in the plugin can do them: that config is tenant-owned and my session is rooted in this repository.

    The version you need is 0.28.0, which exists once the release PR from develop to main merges and the release workflow tags unic-archon-dlc@0.28.0. Before that tag, the Consumer's claude plugin update has nothing newer to fetch.

    Then, in DXP-DesignSystem:

    1. claude plugin update unic-archon-dlc@unic-agent-plugins --scope project. The plugin is installed at project scope and the command defaults to user scope whatever the working directory is; without the flag it fails with "not installed at scope user" (measured 2026-09-05). The Consumer's .claude/settings.json sets "autoUpdate": false, so nothing arrives on its own.
    2. /unic-archon-dlc:setup reconfigure, one run. reconfigure is the report override and the only one (commands/setup.md), and the install step — the four Boxes, the Methods, the managed CLAUDE.md block — runs in both modes, so a plain run first adds nothing this ticket has not already measured (the report-and-change-nothing behaviour was observed on 0.27.0 on 2026-09-03). It offers the change per tenant-owned file and walks the nine needs one at a time, proposing the value it detected for each. (Amended 2026-09-05 by the orchestrator: an earlier version of this comment listed a plain run before reconfigure as a separate step.)
    3. (folded into 2)
    4. Confirm real values for at least install and test. Both come from the project itself: install is whatever its package manager installs with, and test is the script its own root manifest already runs for the suite. Read them off that manifest rather than from anything written here — this plugin names no tool, and neither does a comment written on its behalf. The other seven may stay null; only test is mandatory, and only at the two gates that advance work.

    Without step 4, criterion 4 has removed the fabricated fallback and criterion 9 holds the gates, so run 3's build leg stops at unresolved. That is the correct failure, and it still stops the run.

    What the Consumer run already showed

    unic-dlc-qa run ac71977e ran this branch's Box in DXP-DesignSystem against the config as it stands today — no sdlc_needs block — then paused at uat-gate and was abandoned. Nothing merged, nothing written to the board, and the clone came back byte-identical.

    bootstrap reported the install honestly, and test, e2e and coverage-gate each returned unresolved having fabricated nothing. Then uat-prep's durable block caught the thing this ticket was opened for, unprompted:

    sdlc_needs.test is not declared, so /qa ran no test command. report.md § 3 records pnpm test PASSED, but that was /build invoking the repo default — it is not a check this Box made.

    That is run 2's false pass, register row 41, named by the new block in the Consumer rather than by a human reading the register afterwards.

    Not closing this

    The PR is open and this issue stays open with it. Merging it, and moving the state label to resolved, are yours — nothing in the merge path does either.

  19. added
    resolvedImplemented; ready for a PR
    and removed
    ready-for-agentFully specified, ready for an AFK agent
    on Sep 5, 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