Skip to content

LT-22836: Preserve HermitCrab trace failure facts in Try A Word - #1173

Open
johnml1135 wants to merge 4 commits into
mainfrom
fix/hc-trace-display
Open

johnml1135 wants to merge 4 commits into
mainfrom
fix/hc-trace-display

Conversation

@johnml1135

@johnml1135 johnml1135 commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Fixes LT-22836.

Start here: Src/LexText/ParserCore/FwXmlTraceManager.cs preserves the facts;
Src/Transforms/Presentation/FormatHCTrace.xsl displays them in Try A Word.

Try A Word drops or miswrites facts HermitCrab already supplies. This fixes the
existing callback XML and its presentation against the pinned SIL.Machine 3.9.5,
without rerunning parser checks or changing dependencies.

  • Prefix and suffix environment branches serialize their own values.
  • Terminal environment failure retains the supplied allomorph and writes one
    Environment element per failed alternative.
  • Compounding dispatches on the recorded reason. Version 3.9.5 emits only
    NonHeadProdRestrictMprFeatures here; an unrecognized reason stays unknown.
  • The stylesheet separates environment alternatives and exception-feature lists,
    uses OR for the required at-least-one restrictions, and displays unknown causes
    explicitly.
  • HCSynthByGloss's own trace manager (HcXmlTraceManager.cs) had the same
    run-together environments; it now writes one element per environment, and its
    stylesheet already separates them. HCSynthByGlossTests.TraceListsEachFailedEnvironment
    synthesizes a root from a small grammar whose two environments both fail.
  • Blocking is not recorded. Machine blocks only when a root entry belongs to a
    lexical family, and HCLoader never builds one (FLEx models irregular forms as
    variant entries), so the callback stays empty as on main.

Synthetic before/after trace examples (headless callback/stylesheet cases):

Case Before After
Common / e _, prefix / p _, suffix / _ s Three / e _ Environment values / e _, / p _, / _ s
Failed alternatives for root Environment incorrect for allomorph 'root': / p _/ _ s. Environment incorrect for allomorph 'root': / p _, / _ s.
Compound exception features actual1actual2 / required1required2 actual1 and actual2 / required1 or required2
Unrecognized compound reason Guessed productivity failure or empty reason (Reason: Unknown reason.)

Two end-to-end tests reproduce LT-22836 from a synthetic project loaded through
HCLoader and traced by the real Morpher:
HCLoaderTests.Trace_StemFailingTwoEnvironmentsListsEach (main records
"/ _ a/ _ i" as one environment) and
HCLoaderTests.Trace_CircumfixPatternFailureNamesItsEnvironment (main records an
empty environment). Both fail against main's trace manager and pass here. The
ticket attaches the same data as a FLEx project with manual steps.

Build passed with zero warnings/errors; all 73 ParserCore tests passed, including
14 new callback, transform and end-to-end cases, and all 3 HCSynthByGloss tests
passed, including the new one. Both required hygiene checks passed.
The full repository suite and live desktop checks were not run.

The optional detailed callbacks and additional facts in
sillsdev/machine#534 await a Machine
release and a follow-up FieldWorks PR. The visible behavior is tracked as LT-22836.

Next: review the trace presentation.

Preflight review details

Eight files changed: three production files, four test files and one test grammar. No interface,
package, native, COM, installer, or persisted language-project changes. The trace
XML is transient, and completion remains on the
existing path. Allomorph identities use the existing cache lookup and clickable
id conventions.
New presentation text follows the stylesheet's existing xsl:text convention.

Read-only inspection of Machine's v3.9.5 AnalysisCompoundingRule confirmed that
productivity restrictions are the sole emitted reason on this callback. Other
failure gates must wait for a released version containing the Machine changes.
The serializer never derives a cause from a neighboring trace or repeats a gate.

Validation on Windows/x64:

.\build.ps1 -CommentHygiene -TokenHygiene -BuildTests
.\test.ps1 -CommentHygiene -TokenHygiene -NoBuild -SkipNative -TestProject Src/LexText/ParserCore/ParserCoreTests

The build compiled native prerequisites before managed code and finished with
zero warnings/errors. The test script ran 73/73 passing ParserCore cases and 3/3 HCSynthByGloss cases.
Regression coverage includes distinct circumfix halves, supplied environment
alternatives/allomorph identity, reason-versus-operand attribution, list
punctuation, and both writing directions. Comment hygiene,
token hygiene, PowerShell compatibility, and whitespace checks passed.

The sandboxed restore could not reach NuGet; the network-enabled build succeeded.
No full-suite, live desktop, or screenshot claim is made. Self-review found no
remaining correctness defects. No tracked working documents enter the PR.


This change is Reviewable

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

NUnit Tests

    1 files  ± 0      1 suites  ±0   14m 0s ⏱️ + 3m 38s
6 610 tests +15  6 525 ✅ +15  85 💤 ±0  0 ❌ ±0 
6 619 runs  +15  6 534 ✅ +15  85 💤 ±0  0 ❌ ±0 

Results for commit 9b8b96b. ± Comparison against base commit a90754c.

♻️ This comment has been updated with latest results.

@codecov-commenter

codecov-commenter commented Oct 1, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 39.56%. Comparing base (a90754c) to head (9b8b96b).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1173      +/-   ##
==========================================
+ Coverage   39.49%   39.56%   +0.07%     
==========================================
  Files        1537     1537              
  Lines      354392   354396       +4     
  Branches    41058    41059       +1     
==========================================
+ Hits       139974   140234     +260     
+ Misses     185044   184807     -237     
+ Partials    29374    29355      -19     
Files with missing lines Coverage Δ
Src/LexText/ParserCore/FwXmlTraceManager.cs 34.54% <100.00%> (+34.54%) ⬆️
...ynthByGloss/HCSynthByGlossLib/HcXmlTraceManager.cs 14.74% <100.00%> (+14.56%) ⬆️

... and 5 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jasonleenaylor jasonleenaylor left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Two questions and a note, none blocking:

  • Is there a Jira issue to pin this to?
  • One question inline on the blocking display.
  • HCSynthByGloss has its own copy of the trace manager and stylesheet, which keep the single Environment element, the empty Blocked, and the MatchType test. Perhaps a follow-up Jira issue to write, or something to discuss with Andy.

This review was assisted by Claude Opus 5.5.

<xsl:call-template name="GetAnalysisFont"/>
</xsl:attribute>
<xsl:text>Blocked: </xsl:text>
<xsl:value-of select="Rule"/>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For template blocking, Machine passes the stratum as the rule (SynthesisAffixTemplatesRule.cs:110 in v3.9.2). How does this line read in that case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch: for template blocking it would have read "Blocked: Morphology.", the stratum's name, which looks like a rule. Looking further, neither blocking path can fire from FLEx. Machine only blocks when the root's entry belongs to a lexical family, and HCLoader never builds one (FLEx models irregular forms as variant entries). So I've dropped the Blocked display in 9a536e9; the callback is empty again, as on main.

johnml1135 and others added 2 commits October 13, 2026 13:35
Two tests build a synthetic project, load it with HCLoader and trace
a word through the real Morpher and FwXmlTraceManager:

- a stem whose two environments both fail: main records them as one
  run-together environment, "/ _ a/ _ i"
- a circumfix whose prefix environment its stem does not match: main
  records an empty environment

Both fail on main and pass with this branch's trace manager.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@johnml1135
johnml1135 force-pushed the fix/hc-trace-display branch from 15c1249 to 90eae66 Compare October 13, 2026 18:13
@johnml1135 johnml1135 changed the title Preserve HermitCrab trace failure facts in Try A Word LT-22836: Preserve HermitCrab trace failure facts in Try A Word Oct 13, 2026
johnml1135 and others added 2 commits October 13, 2026 14:23
Machine blocks a word only when its root entry belongs to a lexical
family, and HCLoader never builds one: FLEx models irregular forms as
variant entries. No FLEx project can reach the Blocked callback, so
recording and displaying it was code no user could see. The callback is
empty again, as on main.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
HCSynthByGloss keeps its own copy of the trace manager. Like
FwXmlTraceManager before this branch, it wrapped all of an allomorph's
failed environments in one Environment element, so a synthesis trace
showed "/ _ i/ _ a" as a single environment (LT-22836). It now writes one
element per environment; its stylesheet already separates them.

TraceListsEachFailedEnvironment synthesizes a root from a small grammar
whose two environments both fail. It fails without this change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@johnml1135

johnml1135 commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks, Jason. Your approval was on 15c1249. Since then the PR has grown past what you reviewed, so please take another look at the scope before this merges:

  1. New: HCSynthByGloss fix (9b8b96b). Its copy of the trace manager had the same run-together environments bug, reachable when tracing synthesis. This touches a second project (HCSynthByGlossLib/HcXmlTraceManager.cs) plus a test and test data. If you'd rather keep this PR to FLEx, I can split it out.
  2. Removed: the Blocked display (9a536e9). Answered inline: no FLEx project can reach it, so the callback is empty again, as on main. This shrinks the XSL and test changes you approved.
  3. New: end-to-end tests (90eae66). Two HCLoaderTests.Trace_* tests load a synthetic project through HCLoader and trace it with the real Morpher; both fail on main.

Jira: LT-22836, with a synthetic FLEx project and manual steps attached.

On HCSynthByGloss's other two differences: its empty Blocked callback now matches FLEx's, and its MatchType test is in the one template where the trace does write MatchType.

@AndyBlack, FYI since this touches HCSynthByGloss.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants