Skip to content

Three PR-scoped constraints are declared agent-enforced and never execute — harness-enforcer has no dispatch path #605

Description

@russmiles

Three constraints in HARNESS.md are declared **Enforcement**: agent with
**Scope**: pr, and none of them runs anywhere. There is no CI job, no hook and
no script that executes an agent-enforced constraint. The tier is declared and
inert.

The three

Constraint Tool declared
PRs have adjudicated objections harness-enforcer
PRs have adjudicated choice stories harness-enforcer
Specs cite the source of a claimed convention harness-enforcer

.github/workflows/harness.yml is the PR-constraint job, and its own header says
what it covers: "Runs PR-scoped deterministic constraints from
HARNESS.md."
Every step in it is a deterministic tool — markdownlint, secret
scan, bash -n, ShellCheck, frontmatter check, sentinel integrity, decision-record
validation. grep -rn 'harness-enforcer' .github/workflows/ returns nothing.

So the job named Enforce PR constraints passes on every PR without having
evaluated any of the three.

Observed on PR #604

PR #604 carries a spec dated 2026-08-25 — after the 2026-04-27 cutoff in the
PRs have adjudicated choice stories rule — and no choice-story record at
docs/superpowers/stories/. All eleven checks passed, including Enforce PR
constraints
.

The gap was found by reading the constraint, not by CI. That is the whole
finding: the rule's own text says it "requires an active exemption claim, not
silent elision through spec-first bypass"
, and silent elision is exactly what
the tooling permits, because nothing evaluates the rule.

Why this matters more than three missing checks

HARNESS.md's Status block counts these three among its enforced constraints.
A constraint that is declared, counted, and never executed is the defect class
the in-force decision record already names —
HDR-2026-08-25-four-mechanisms-report-the-reassuring-answer-when-they-cannot-determine-the-real-one:
a mechanism must not report a pass on the strength of a property weaker than the
one it names. "Enforce PR constraints — pass" names more than it checked.

It is also the same shape as the Template currency GC rule being deleted in
#601: declared deterministic, no tool behind it, absent from gc.yml. That one
is being removed because nothing backed it. These three are worth backing
rather than removing, because the behaviour they describe is wanted.

Two of the three may not need an agent at all

.github/workflows/consultation-disposition-check.yml already enforces a
structurally identical rule deterministically: every voice in a consultation
record must carry a disposition, and no two may share an outcome. It is the
working precedent.

  • PRs have adjudicated objections — "no disposition: pending and no
    disposition_rationale: null in the matching objection record" is a schema
    check. The record's own frontmatter is machine-readable, and
    objection-taxonomy-check.yml already parses these files for categories and
    severities; it simply does not look at dispositions.
  • PRs have adjudicated choice stories — same shape against
    docs/superpowers/stories/<slug>.md, plus "a record exists for each
    non-exempt spec".

Both rules carry a judgement clause — "'Resolved' is a judgment call on
rationale quality, not a schema check"
— so a deterministic check cannot cover
them fully. But it can cover the falsifiable half (presence, no pending,
no null rationale) and that is the half that failed silently on #604. Whether the
judgement half is worth an agent, or is better left to human review, is the
design question.

Specs cite the source of a claimed convention is genuinely semantic and is
the one with a real case for an agent.

What the change has to decide

  1. Deterministic-first or agent-first. Following the consultation precedent
    for the two disposition rules is cheap, fast and needs no model call. Doing so
    means their Enforcement field changes from agent to deterministic and
    the rule text acknowledges the judgement half is uncovered — which is more
    honest than today, where it claims full agent coverage and gets none.
  2. Whether harness-enforcer gets a dispatch path at all, or whether the
    agent tier is retired for PR scope. Related: Give TDAD Layers 2 and 3 a dispatch path — 50 scenarios are written and never executed #583 makes the same argument for
    TDAD Layers 2 and 3 — "50 scenarios are written and never executed."
  3. The 15 agent-enforced GC rules. Out of scope here (they run on a cadence,
    not per PR) but they share the tier, and whatever is decided about dispatch
    affects them. Named so the decision is made knowingly.
  4. What the Status block should say while a constraint is declared but
    unexecuted. /harness-audit counts these three today.

Non-goals

  • Removing the three constraints. The behaviour they describe is wanted; only
    the enforcement is missing.
  • Rewriting harness.yml's deterministic steps.
  • The GC-rule side of the agent tier.

Process

  • Spec-first applies if this changes constraint enforcement levels or adds a
    dispatch path — a behaviour change, not exempt via chore/fix.
  • Version bump: minor if HARNESS.md enforcement fields or workflows change
    under ai-literacy-superpowers/.
  • Worth an /harness-assay first: "a constraint tier that is declared, counted
    and never executed" is exactly the shape the Assayer characterises, and it
    would give the spec evidence rather than an argument.

Related

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions