LearnNewsExamplesServices
Frontmatter
id16333
titleagent-preflight change-class map rejects the live test(...) commit convention
stateClosed
labels
bugaibuild
assignees[]
createdAtAug 2, 2026, 4:12 AM
updatedAtAug 2, 2026, 1:22 PM
githubUrlhttps://github.com/neomjs/neo/issues/16333
authorneo-kimi-phoebe
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 2, 2026, 1:22 PM

agent-preflight change-class map rejects the live test(...) commit convention

neo-kimi-phoebe
neo-kimi-phoebe commented on Aug 2, 2026, 4:12 AM

Context

Friction captured from PR #16319 (2026-08-02, this session): a test-only PR (new e2e spec witness, zero runtime delta) had no valid --change-class declaration — agent-preflight rejected test(e2e): … under both capability ("requires feat") and zero-delta ("requires chore"). The sanctioned escape (run preflight without semantic inputs) works but silently skips the class-consistency gate the tool exists to enforce.

The Problem

CHANGE_CLASS_TO_TYPE (buildScripts/util/agent-preflight.mjs:38-42) maps each declared class to exactly ONE conventional-commit type: capability→feat, restoration→fix, zero-delta→chore. But the repo's live commit convention includes test(...) subjects for test-only deltas — 8 merged test(...) subjects in the last 14 days alone (git log origin/dev --since="14 days ago": test(wake), test(harness), test(ci), test(workstation) ×2, test(ai), test(tooling), test:). Every one of those PRs either bypassed the semantic gate or mislabeled. The gate's model of the convention and the convention itself have drifted apart — and the friction lands precisely on the disciplined author who declares semantics.

The Architectural Reality

  • The class gate was introduced by #16111 (closed: "Make agent commit-type selection ordered and locally enforced") to stop capability-mislabeling (chore for capability work, per #10061). Its enforcement value is real — the gap is the type vocabulary, not the gate.
  • CONVENTIONAL_TYPE_PATTERN (agent-preflight.mjs:34) already parses any lowercase type; the restriction lives only in the one-type-per-class map.

The Fix

Widen the map to type sets per class and let history decide which set members are live:

  • zero-delta['chore', 'test', 'docs', 'ci', 'build'] (deltas that change neither runtime behavior nor capability — the repo's actual zero-delta vocabulary)
  • capability['feat'], restoration['fix'] (unchanged — these two classes are the mislabeling risk #16111/#10061 targeted; keep them strict)

Add a spec case: a declared test(...) subject under zero-delta validates; under capability/restoration still rejects.

Acceptance Criteria

  • agent-preflight --change-class zero-delta --commit-subject "test(e2e): add witness (#N)" passes validation
  • --change-class capability with a test(...) subject still fails (the mislabeling guard is preserved)
  • pull-request-workflow.md §3.1 updated to state the zero-delta type set explicitly (the workflow and the tool must tell the same story)
  • Spec coverage for both directions

Out of Scope

  • Re-litigating the class system itself (#16111 settled it — this is the vocabulary completion it left open)
  • Allowing arbitrary types (the set is the boundary; style/refactor/perf can join later by the same evidence rule)

Related

  • #16111 (the gate's origin, closed) · #10061 (the original mislabeling correction)
  • Friction origin: PR #16319 (test-only spec PR forced onto the no-semantic-inputs path)

Live latest-open sweep: checked latest 20 open issues at 2026-08-02T02:1xZ; no equivalent found. KB sweep surfaced #16111 (closed; this is its vocabulary-completion successor, not a duplicate). A2A in-flight sweep: no claim on this scope in the last 60 min.

Origin Session ID: 14f1d6fa-235a-4101-88d4-c9490e3f7fd5

Retrieval Hint: "agent-preflight change-class test-prefix convention drift"

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
CHANGE_CLASS_TO_TYPES (renamed export, agent-preflight.mjs) #16111's ordered-class contract Frozen map of class → frozen type array; zero-delta → {chore, test, docs, ci, build}; capability/restoration strict single-member sets old scalar CHANGE_CLASS_TO_TYPE removed (zero external consumers — grep receipt, 2026-08-02) JSDoc comment on the map unit spec
validateChangeClass().expectedTypes same Array-valued observation; isolated copy per call — mutating a result never changes later validations (regression-witnessed) n/a @returns JSDoc regression spec
Error rendering same Single-member set: requires `feat` ; multi-member: requires one of chore, test, docs, ci, build. n/a unit spec
CLI success line same Prints the joined set (maps to chore, test, docs, ci, build) n/a CLI receipt in PR body
pull-request-workflow.md §3.1 the PR-lifecycle atlas Names the type set + the "labels, not proof — the author's truthful declaration stays the class authority" framing n/a the atlas itself manifest lint (21879→21976 B, ≤ 22000 budget)

Per-member evidence (14-day origin/dev history, 2026-08-02): test 20 · docs 22 · chore 65 · build 4 · ci 0. ci is admitted by convention (CI-config deltas are definitionally runtime-zero-delta), explicitly NOT by count — the gate maps the author-declared class to the allowed set; a prefix never proves the class.

tobiu referenced in commit 5703e0d - "fix(build): admit the live zero-delta type vocabulary in agent-preflight (#16333) (#16335) on Aug 2, 2026, 1:22 PM
tobiu closed this issue on Aug 2, 2026, 1:22 PM