ceilf6 / ceilf6/FrontAgent

[Bug] syntax_validity flags legitimate code as block — apostrophes, template literals, JSX text

Open
#413 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
119
Forks
19
PR merge metrics
No merged PRs in 30d

Description

What

checkSyntaxValidity decides "unclosed string" by counting quote characters per line (packages/hallucination-guard/src/checks/syntax-validity.ts:185-216). Any legitimate line with an odd number of quotes is reported, and the check result carries severity: 'block'.

Measured against the built guard:

input verdict
export const msg = "it's fine"; block
a multi-line template literal block
export const P = () => <p>Don't panic</p>; block
export const a = 1; pass
export const a = { (genuinely broken) block

Three of the four blocking verdicts are false positives, and they cover extremely common code: any apostrophe inside a string, any multi-line template literal, any JSX text with a contraction.

Why it matters

Today these are post-write verdicts: the step is marked failed but the file stays on disk, so the damage is a misleading failure rather than lost work. That makes it easy to miss.

It became load-bearing in #402, which initially granted syntax_validity write-veto and rollback-trigger power. With that wiring, a file containing it's would not have been written at all, and a legitimate file already on disk could have been deleted by a create snapshot rollback (unlinkSync). #402 was changed to use a narrow, high-precision predicate instead (markdown fence in a code file — the failure actually observed in the 2026-07-12 eval), precisely because this check is not reliable enough to gate a write.

Note this is the opposite failure direction from #406 (guard passes prose-as-code). Both come from the same root cause: the checker does not parse.

Suggested direction

Parse instead of counting. typescript is already a devDependency of both @frontagent/hallucination-guard and @frontagent/core; ts.createSourceFile(..., /*setParentNodes*/ false) with parseDiagnostics gives real syntactic errors and would fix both directions at once.

The packaging question is what stops this being a drive-by fix: typescript would have to become a runtime dependency of the guard, which every install then carries. That is a maintainer call, which is why it is filed rather than folded into #402.

Interim state

Until this is fixed, no caller should give syntax_validity veto power over a write. #402 documents this in executor.ts at the veto predicate.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/hallucination-guard/src/checks/syntax-validity.ts:185-216 and read the veto predicate documented in #402's executor.ts. Compare the listed false positives with the genuinely broken example, then assess parseDiagnostics and the runtime dependency implications. Done means legitimate apostrophes, template literals, and JSX text no longer block while real syntax errors still do.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
58/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.