diff --git a/GenI.cabal b/GenI.cabal
--- a/GenI.cabal
+++ b/GenI.cabal
@@ -1,5 +1,5 @@
 Name:           GenI
-Version:        0.24.2
+Version:        0.24.3
 License:        GPL
 License-file:   LICENSE
 Author:         Carlos Areces and Eric Kow
@@ -10,7 +10,7 @@
 Maintainer:     geni-users@loria.fr
 Build-Type:     Simple
 Cabal-Version: >=1.14
-data-files: AUTHORS, README.markdown, NEWS, GenI.cabal,
+data-files: AUTHORS, README.markdown, changelog, GenI.cabal,
             examples/artificial/lexicon,
             examples/artificial/trees,
             examples/artificial/suite,
diff --git a/NEWS b/NEWS
deleted file mode 100644
--- a/NEWS
+++ /dev/null
@@ -1,220 +0,0 @@
-GenI 0.24, 18 Sep 2013
-----------------------
-Note that the changes between this release and 0.20 are considered to be under
-the BSD3 license.  GenI overall remains dual-licensed under the GPL and any
-commercial-use terms you may wish to negotiate with INRIA. Having secured the
-rights to use GenI 0.20, you may freely use GenI 0.24 in a similar fashion.
-
-CHANGES TO WATCH OUT FOR
-
-* Server/GUI changes: Semantic input must be full input.
-  - Before: `foo(x) bar(y z)`
-  - After:  `semantics:[foo(x) bar(y z)]`
-* Customisable semantics : now you can accept any arbitrary
-  input for which you can define a mapping to a GenI-style test case
-* API change: the custom semantics argument is mandatory
-* More extensive documentation
-
-GUI
-
-* Visual distinction between explicit null adjunction constraints
-  (marked NA) and constraints inserted by GenI (marked INA)
-* Bugfixes (now retains show-feature state across debugger steps)
-* More informative top/bot unification failure diagnostics in the
-  trash
-
-GENERAL
-
-* New "guided realisation" optimisation (focus on one polarity
-  path at a time)
-* Fixed errors where top/bottom unification wasn't being done
-* Builds with haskell-platform 2013.2.0.0
-
-GenI 0.22, 14 Apr 2012
-----------------------
-Note that the changes between this release and 0.20 are considered to be under
-the BSD3 license.  GenI overall remains dual-licensed under the GPL and any
-commercial-use terms you may wish to negotiate with INRIA. Having secured the
-rights to use GenI 0.20, you may freely use GenI 0.22 in a similar fashion.
-
-CHANGES TO WATCH OUT FOR
-
-* Separation of geni and geni-gui into two packages;
-  simpler installation
-* Now using the top feature for lemanchors instead of bot
-* Empty disjunctions forbidden in unification variables
-* JSON input/output to morph processors have changed
-* Lexical selection unifies semantics of tree schema + lemma with
-  input semantics.
-
-GUI
-
-* New results tab with reminder of inputs
-* Add gui element to display unanchored lexical selection.
-* Jump to new tab in debugger panel when created.
-* Update gui to use Pretty instead of Show
-* Rename $algo-session tab to "tree assembly"
-* Make warnings resizable.
-* Fix display of path equations with 'interface' in them.
-* Fix #50 - load button has no effect.
-* Fix #49 - correct order that leaf nodes are returned.
-* Show GenI version in About box.
-* Add detect polarities and root feature editor to main gui.
-
-DOCUMENTATION
-
-* Literate GenI and genimanual replaced with
-  http://projects.haskell.org/GenI/manual
-
-GENERAL
-
-* Builds with GHC 7
-* Core behaviour
-     * Early null-adjunction and semfilter obligatory
-     * Handling of zero-literal semantic items restored
-     * Unconstrained polarities in automaton construction.
-       This makes it possible to do polarity detection with only a
-       weakly specified root feature like [cat:_], and without needing
-       the relevant feature to be implemented everywhere.
-
-* Flags:
-     * --trees (used to be --macros; latter is deprecated)
-     * --batchdir now optional (defaults to a new temp dir)
-     * --maxsteps (stop after N steps)
-     * --extrapol REMOVED (use root feature instead)
-* Logging facility (not used much in GenI yet)
-  Can be configured in ~/.geni/config.yaml, for example
-  logging:
-   -
-     name     : NLP.GenI.Console
-     level    : WARN
-     format   : simple "$msg"
-   -
-     name     : NLP.Geni.LexicalSelection
-     level    : DEBUG
-     format   : simple "$utcTime $loggername $msg"
-     handler  : stderr
-* Less repetition in warnings (hopefully easier to read)
-* More hiding of constructors for safety
-* New enrichment option for setting co-anchors (foo.lex=hello)
-* Lexical selection performance enhancements
-* Variables that only occur once are converted to anonymous,
-  should make unification a bit more efficient
-* Fix #39: reject malformed root feature input.
-* New feature:
-  * Variables with constraints on their possible values (?X/foo|bar)
-  * Fancy disjunctions: tree schemata now allow disjunctions of
-    unification variables (but not recursive). These must flatten down
-    to plain old atomic disjunction once converted to elementary trees
-
-* Time metric in statistics (Laura Perez)
-* Do top/bottom unification on na-constrained nodes during initialisation.
-* Polarity detection relaxed to work with constrained variables too.
-  (?X/foo|bar gives the result as foo|bar)
-* Bugfix in interpretation of root feature (it should be sorted).
-* Flags:
-  * --rootfeat always assumed, but defaults to '[cat:_]'
-  * '-r' a short command line option for '--rootfeat'.
-
-LIBRARY
-
-* Somewhat safer and easier to understand API
-  (still no stability yet)
-* Replace String with Text in GeniVal
-* Replace Show abuse with custom Pretty class
-* Slightly less stateful (no target semantics in state)
-* Much rearranging and renaming (sorry!)
-* New: ability to provide custom lexical selection action
-* New: ability to provide custom morph postprocessing action
-* de-haskell98 (Gwern Branwen)
-* No more null builder.
-
-TOOLS (darcs get --lazy http://code.haskell.org/GenI)
-
-* new tool, genireport: summarise batch generation results
-* geniserver now talks over HTTP using a JSON format
-* Use Sylvain Salvati's xmg2geni.xsl instead of geniconvert.
-    * xmg2geni: fix treatment of missing lexemes.
-    * xmg2geni: treat type=coanchor as other nodes in GenI.
-* geniwrapper: illustrates C wrapper of GenI API
-
-GenI 0.20, 29 Sep 2009
-----------------------
-- NON BACKWARD-COMPATIBLE CHANGES
-
-  * GHC 6.8 or higher now required (GHC 6.10 + Haskell Platform preferred)
-  * Input files now *assumed* to be UTF-8 encoded
-    (output still ISO8859-1; hopefully locale-based in GHC 6.12)
-  * Interface between GenI and morphological realiser now uses a JSON format.
-  * Rootfeat optimisation now mandatory (flag no longer recognised)
-
-- NEW FUNCTIONALITY
-
-  * new flag --version now works and reports version from Cabal file
-  * new flag --dump dumps derivation output to stdout in JSON format
-  * new flag --ranking foo ranks outputs according to OT-style constraints expressed in foo
-  * --batchdir now works with --testcase
-  * --batchdir now dumps derivations and statistics in JSON format
-  * --batchdir now works with instructions files
-  * --metrics always expands 'default' to the default metrics
-    (in addition to any other statistics you request)
-  * new optimisation: early null-adjunction detection
-
-- QUALITY ASSURANCE
-
-  * Reference manual in docs/genimanual.pdf (make docs)
-  * cabal install -fgui and cabal install produce the same underlying library
-    only the executable is different
-  * Easier GUI installation for MacOS X (application bundles now built
-    automatically; no manual intervention required)
-  * Adopted odd/even convention to distinguish devel builds from stable ones
-    (eg. GenI 0.21.x is devel whereas GenI 0.20.x is stable)
-
-GenI 0.17.4, 6 Apr 2009
------------------------
-* GHC 6.6 support
-
-* GUI disabled by default
-
-GenI 0.17.3, 3 Apr 2009
------------------------
-* Simplified build method
-  * one single cabal package instead of two
-  * cabal configure -f-gui to disable GUI
-  * makefile stripped out
-
-* Lexical selection on empty semantics now allowed
-  * This is so that the zero-literal semantics mechanism can work again
-
-* Better help text
-
-* Baked-in unit testing (geni --unit-test)
-
-GenI 0.10, 11 Dec 2006
-----------------------
-* Performance much improved after Haskell profiling
-* Pre-compiled grammars option, geniserver (buggy)
-
-GenI 0.9, 8 Dec 2006
---------------------
-* Switched to new syntax: variables now must be prefixed with '?'
-* Switched from Alex/Happy to Parsec
-* Added API documentation via haddock
-
-GenI 0.8, 16 Sep 2005
----------------------
-* Support for latin-1 characters using Unicode wxhaskell
-* Added a configure script and an install target in Makefile
-* Changed from use of configuration files to use of command line switches
-* Full configuration GUI
-* Implementation of atomic disjunction
-* --ignore-semantics mode (Jackie Lai)
-
-GenI 0.7, 8 June 2005
----------------------
-* Upgraded to ghc 6.4, wxwidgets 2.6, wxhaskell 0.9.4
-
-GenI 0.6, 3 May 2005
----------------------
-* User interface fixes (Window size bugs)
-* Interface with Yannick Parmientier's selection module
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -22,13 +22,13 @@
 2. Install the basic version first. If you just want the
    last stable release of GenI,
 
-           cabal install GenI geniserver
+           cabal install GenI geniserver geni-util
 
        However, if you want to install the unstable version
    from source, change to the directory this README is in
    and
 
-           cabal install . ./geniserver
+           cabal install . ./geniserver ./geni-util
 
 ## Graphical interface
 
diff --git a/changelog b/changelog
new file mode 100644
--- /dev/null
+++ b/changelog
@@ -0,0 +1,236 @@
+GenI 0.24.3 15 Nov 2013
+-----------------------
+BUGFIXES:
+
+* Lexical selection: trees that fail enrichment due to unification failure are
+  now discarded
+
+  Previously, there was some confusion over whether the expected behaviour was
+  for this to be an error or warning. The behaviour after this fix is that
+  missing nodes trigger a warning, an unification failures trigger an error
+  (discarded tree)
+
+* Realisation: When anonymising singleton variables, GenI preserves their
+  constraints. This should fix some subtle overgeneration problems that may
+  arise in automatically generated grammars
+
+GenI 0.24, 18 Sep 2013
+----------------------
+Note that the changes between this release and 0.20 are considered to be under
+the BSD3 license.  GenI overall remains dual-licensed under the GPL and any
+commercial-use terms you may wish to negotiate with INRIA. Having secured the
+rights to use GenI 0.20, you may freely use GenI 0.24 in a similar fashion.
+
+CHANGES TO WATCH OUT FOR
+
+* Server/GUI changes: Semantic input must be full input.
+  - Before: `foo(x) bar(y z)`
+  - After:  `semantics:[foo(x) bar(y z)]`
+* Customisable semantics : now you can accept any arbitrary
+  input for which you can define a mapping to a GenI-style test case
+* API change: the custom semantics argument is mandatory
+* More extensive documentation
+
+GUI
+
+* Visual distinction between explicit null adjunction constraints
+  (marked NA) and constraints inserted by GenI (marked INA)
+* Bugfixes (now retains show-feature state across debugger steps)
+* More informative top/bot unification failure diagnostics in the
+  trash
+
+GENERAL
+
+* New "guided realisation" optimisation (focus on one polarity
+  path at a time)
+* Fixed errors where top/bottom unification wasn't being done
+* Builds with haskell-platform 2013.2.0.0
+
+GenI 0.22, 14 Apr 2012
+----------------------
+Note that the changes between this release and 0.20 are considered to be under
+the BSD3 license.  GenI overall remains dual-licensed under the GPL and any
+commercial-use terms you may wish to negotiate with INRIA. Having secured the
+rights to use GenI 0.20, you may freely use GenI 0.22 in a similar fashion.
+
+CHANGES TO WATCH OUT FOR
+
+* Separation of geni and geni-gui into two packages;
+  simpler installation
+* Now using the top feature for lemanchors instead of bot
+* Empty disjunctions forbidden in unification variables
+* JSON input/output to morph processors have changed
+* Lexical selection unifies semantics of tree schema + lemma with
+  input semantics.
+
+GUI
+
+* New results tab with reminder of inputs
+* Add gui element to display unanchored lexical selection.
+* Jump to new tab in debugger panel when created.
+* Update gui to use Pretty instead of Show
+* Rename $algo-session tab to "tree assembly"
+* Make warnings resizable.
+* Fix display of path equations with 'interface' in them.
+* Fix #50 - load button has no effect.
+* Fix #49 - correct order that leaf nodes are returned.
+* Show GenI version in About box.
+* Add detect polarities and root feature editor to main gui.
+
+DOCUMENTATION
+
+* Literate GenI and genimanual replaced with
+  http://projects.haskell.org/GenI/manual
+
+GENERAL
+
+* Builds with GHC 7
+* Core behaviour
+     * Early null-adjunction and semfilter obligatory
+     * Handling of zero-literal semantic items restored
+     * Unconstrained polarities in automaton construction.
+       This makes it possible to do polarity detection with only a
+       weakly specified root feature like [cat:_], and without needing
+       the relevant feature to be implemented everywhere.
+
+* Flags:
+     * --trees (used to be --macros; latter is deprecated)
+     * --batchdir now optional (defaults to a new temp dir)
+     * --maxsteps (stop after N steps)
+     * --extrapol REMOVED (use root feature instead)
+* Logging facility (not used much in GenI yet)
+  Can be configured in ~/.geni/config.yaml, for example
+  logging:
+   -
+     name     : NLP.GenI.Console
+     level    : WARN
+     format   : simple "$msg"
+   -
+     name     : NLP.Geni.LexicalSelection
+     level    : DEBUG
+     format   : simple "$utcTime $loggername $msg"
+     handler  : stderr
+* Less repetition in warnings (hopefully easier to read)
+* More hiding of constructors for safety
+* New enrichment option for setting co-anchors (foo.lex=hello)
+* Lexical selection performance enhancements
+* Variables that only occur once are converted to anonymous,
+  should make unification a bit more efficient
+* Fix #39: reject malformed root feature input.
+* New feature:
+  * Variables with constraints on their possible values (?X/foo|bar)
+  * Fancy disjunctions: tree schemata now allow disjunctions of
+    unification variables (but not recursive). These must flatten down
+    to plain old atomic disjunction once converted to elementary trees
+
+* Time metric in statistics (Laura Perez)
+* Do top/bottom unification on na-constrained nodes during initialisation.
+* Polarity detection relaxed to work with constrained variables too.
+  (?X/foo|bar gives the result as foo|bar)
+* Bugfix in interpretation of root feature (it should be sorted).
+* Flags:
+  * --rootfeat always assumed, but defaults to '[cat:_]'
+  * '-r' a short command line option for '--rootfeat'.
+
+LIBRARY
+
+* Somewhat safer and easier to understand API
+  (still no stability yet)
+* Replace String with Text in GeniVal
+* Replace Show abuse with custom Pretty class
+* Slightly less stateful (no target semantics in state)
+* Much rearranging and renaming (sorry!)
+* New: ability to provide custom lexical selection action
+* New: ability to provide custom morph postprocessing action
+* de-haskell98 (Gwern Branwen)
+* No more null builder.
+
+TOOLS (darcs get --lazy http://code.haskell.org/GenI)
+
+* new tool, genireport: summarise batch generation results
+* geniserver now talks over HTTP using a JSON format
+* Use Sylvain Salvati's xmg2geni.xsl instead of geniconvert.
+    * xmg2geni: fix treatment of missing lexemes.
+    * xmg2geni: treat type=coanchor as other nodes in GenI.
+* geniwrapper: illustrates C wrapper of GenI API
+
+GenI 0.20, 29 Sep 2009
+----------------------
+- NON BACKWARD-COMPATIBLE CHANGES
+
+  * GHC 6.8 or higher now required (GHC 6.10 + Haskell Platform preferred)
+  * Input files now *assumed* to be UTF-8 encoded
+    (output still ISO8859-1; hopefully locale-based in GHC 6.12)
+  * Interface between GenI and morphological realiser now uses a JSON format.
+  * Rootfeat optimisation now mandatory (flag no longer recognised)
+
+- NEW FUNCTIONALITY
+
+  * new flag --version now works and reports version from Cabal file
+  * new flag --dump dumps derivation output to stdout in JSON format
+  * new flag --ranking foo ranks outputs according to OT-style constraints expressed in foo
+  * --batchdir now works with --testcase
+  * --batchdir now dumps derivations and statistics in JSON format
+  * --batchdir now works with instructions files
+  * --metrics always expands 'default' to the default metrics
+    (in addition to any other statistics you request)
+  * new optimisation: early null-adjunction detection
+
+- QUALITY ASSURANCE
+
+  * Reference manual in docs/genimanual.pdf (make docs)
+  * cabal install -fgui and cabal install produce the same underlying library
+    only the executable is different
+  * Easier GUI installation for MacOS X (application bundles now built
+    automatically; no manual intervention required)
+  * Adopted odd/even convention to distinguish devel builds from stable ones
+    (eg. GenI 0.21.x is devel whereas GenI 0.20.x is stable)
+
+GenI 0.17.4, 6 Apr 2009
+-----------------------
+* GHC 6.6 support
+
+* GUI disabled by default
+
+GenI 0.17.3, 3 Apr 2009
+-----------------------
+* Simplified build method
+  * one single cabal package instead of two
+  * cabal configure -f-gui to disable GUI
+  * makefile stripped out
+
+* Lexical selection on empty semantics now allowed
+  * This is so that the zero-literal semantics mechanism can work again
+
+* Better help text
+
+* Baked-in unit testing (geni --unit-test)
+
+GenI 0.10, 11 Dec 2006
+----------------------
+* Performance much improved after Haskell profiling
+* Pre-compiled grammars option, geniserver (buggy)
+
+GenI 0.9, 8 Dec 2006
+--------------------
+* Switched to new syntax: variables now must be prefixed with '?'
+* Switched from Alex/Happy to Parsec
+* Added API documentation via haddock
+
+GenI 0.8, 16 Sep 2005
+---------------------
+* Support for latin-1 characters using Unicode wxhaskell
+* Added a configure script and an install target in Makefile
+* Changed from use of configuration files to use of command line switches
+* Full configuration GUI
+* Implementation of atomic disjunction
+* --ignore-semantics mode (Jackie Lai)
+
+GenI 0.7, 8 June 2005
+---------------------
+* Upgraded to ghc 6.4, wxwidgets 2.6, wxhaskell 0.9.4
+
+GenI 0.6, 3 May 2005
+---------------------
+* User interface fixes (Window size bugs)
+* Interface with Yannick Parmientier's selection module
diff --git a/examples/artificial/lexicon b/examples/artificial/lexicon
--- a/examples/artificial/lexicon
+++ b/examples/artificial/lexicon
@@ -67,3 +67,22 @@
 
 trace-good tr-good () semantics:[trace()]
 trace-bad  tr-bad  () semantics:[trace()]
+
+enrichment-good enrichment ()
+equations:[anchor.bot.foo:+]
+semantics:[enrichment-good()]
+
+enrichment-bad  enrichment ()
+equations:[anchor.bot.foo:-]
+semantics:[enrichment-bad()]
+
+enrichment-restraint-good enrichment-restraint ()
+equations:[anchor.bot.foo:+]
+semantics:[enrichment-restraint-good()]
+
+enrichment-missing-node-good enrichment ()
+equations:[foo.bot.foo:+]
+semantics:[enrichment-missing-node-good()]
+
+single-user-var single-use-var ()
+semantics:[single-use-var()]
diff --git a/examples/artificial/suite b/examples/artificial/suite
--- a/examples/artificial/suite
+++ b/examples/artificial/suite
@@ -34,3 +34,12 @@
 variablecat semantics:[variablecat()]
 
 trace-good semantics:[trace()[T1]]
+
+enrichment-good
+semantics:[enrichment-good()]
+
+enrichment-restraint-good
+semantics:[enrichment-restraint-good()]
+
+enrichment-missing-node-good
+semantics:[enrichment-missing-node-good()]
diff --git a/examples/artificial/suite-bad b/examples/artificial/suite-bad
--- a/examples/artificial/suite-bad
+++ b/examples/artificial/suite-bad
@@ -14,3 +14,8 @@
 
 interface-unification semantics:[interface()]
 trace-bad  semantics:[trace()[T2]]
+
+enrichment-bad semantics:[enrichment-bad()]
+
+single-use-var
+semantics:[single-use-var()]
diff --git a/examples/artificial/trees b/examples/artificial/trees
--- a/examples/artificial/trees
+++ b/examples/artificial/trees
@@ -158,3 +158,16 @@
 tr-bad() initial
 X anchor [cat:x]![cat:y]
 trace:[T2]
+
+enrichment() initial
+X anchor [cat:x]![foo:+]
+
+enrichment-restraint:e1() initial % meant to fail
+X anchor [cat:x]![foo:-]
+
+enrichment-restraint:e2() initial % meant to be left behind
+X anchor [cat:x]![]
+
+% should not be anonymised away
+single-use-var() initial
+X anchor [cat:x]![cat:?X/y]
diff --git a/src/NLP/GenI/GeniVal/Internal.hs b/src/NLP/GenI/GeniVal/Internal.hs
--- a/src/NLP/GenI/GeniVal/Internal.hs
+++ b/src/NLP/GenI/GeniVal/Internal.hs
@@ -386,12 +386,18 @@
 -- | Anonymise any variable that occurs only once in the object
 anonymiseSingletons :: (Collectable a, DescendGeniVal a) => a -> a
 anonymiseSingletons x =
-   replace subst x
+   descendGeniVal anonymiseIfLonely x
  where
-   subst = Map.map (const mkGAnon) . Map.filter (== 1)
-           -- merge counts for same var, different constraints
-         . Map.fromListWith (+) . map (first fst) . Map.toList
-         $ collect x Map.empty
+   anonymiseIfLonely v =
+       case gLabel v of
+           Just l | l `elem` lonely -> anonymise v
+           _                        -> v
+   anonymise v = v { gLabel = Nothing }
+   lonely = Map.keys
+          . Map.filter (== 1)
+          -- merge counts for same var, different constraints
+          . Map.fromListWith (+) . map (first fst) . Map.toList
+          $ collect x Map.empty
 
 -- | 'finaliseVarsById' appends a unique suffix to all variables in
 -- an object.  This avoids us having to alpha convert all the time
diff --git a/src/NLP/GenI/LexicalSelection.hs b/src/NLP/GenI/LexicalSelection.hs
--- a/src/NLP/GenI/LexicalSelection.hs
+++ b/src/NLP/GenI/LexicalSelection.hs
@@ -307,7 +307,7 @@
 -- ** Enrichment
 -- ----------------------------------------------------------------------
 
--- | See <http://projects.haskell.org/manual/lexical-selection>
+-- | See <http://kowey.github.io/GenI/manual/lexical-selection.html>
 --   on enrichement
 enrich :: LexEntry -> SchemaTree -> LexCombine SchemaTree
 enrich l t = do
@@ -327,39 +327,46 @@
 
 -- *** 'enrich' helpers
 
+data EnrichmentResult = EnrSuccess SchemaTree Subst
+                      | EnrNotFound
+                      | EnrFailed
+
 -- | Helper for 'enrich' (enrich by single path equation)
 enrichBy :: SchemaTree
          -> PathEqPair
          -> LexCombine SchemaTree
 enrichBy t eq@(eqLhs, _) =
     case maybeEnrichBy t eq of
-        Nothing     -> lexTell enrichErr >> return t
-        Just (t2,_) -> return t2
+        EnrNotFound     -> return t -- warning generated separately :-(
+        EnrFailed       -> lexTell enrichErr   >> mzero
+        EnrSuccess t2 _ -> return t2
   where
-    enrichErr = SchemaError [pidname t] (EnrichError (PeqJust eqLhs))
+    enrichErr   = SchemaError [pidname t] $
+        EnrichError (PeqJust eqLhs)
 
 -- | Helper for 'enrichBy'
 maybeEnrichBy :: SchemaTree
               -> PathEqPair
-              -> Maybe (SchemaTree, Subst)
-maybeEnrichBy t (eqLhs, eqVal) = do
-    node <- seekCoanchor eqLhs t
-    case eqLhs of
-        PeqFeat _ eqTop eqAtt -> do
-            let (get, set) = case eqTop of
-                               Top     -> (gup,   \n x -> n { gup = x })
-                               Bottom  -> (gdown, \n x -> n { gdown = x})
-            (fs, sub) <- hush $ enrichFeat (AvPair eqAtt eqVal) (get node)
-            let t2 = fixNode (set node fs) (replace sub t)
-            return (t2, sub)
-        PeqLex _ -> do
-             vs <- gConstraints eqVal
-             let node2 = node { glexeme = FL.fromFL vs }
-                 t2    = fixNode node2 t
-             return (t2, Map.empty)
+              -> EnrichmentResult
+maybeEnrichBy t (eqLhs, eqVal) =
+    maybe EnrNotFound enrichNode $ seekCoanchor eqLhs t
   where
     fixNode n mt =
         mt { tree = repNodeByNode (matchNodeName eqLhs) n (tree mt) }
+    enrichNode node = fromMaybe EnrFailed $
+        case eqLhs of
+            PeqFeat _ eqTop eqAtt -> do
+                let (get, set) = case eqTop of
+                                   Top     -> (gup,   \n x -> n { gup = x })
+                                   Bottom  -> (gdown, \n x -> n { gdown = x})
+                (fs, sub) <- hush $ enrichFeat (AvPair eqAtt eqVal) (get node)
+                let t2 = fixNode (set node fs) (replace sub t)
+                return $ EnrSuccess t2 sub
+            PeqLex _ -> do
+                 vs <- gConstraints eqVal
+                 let node2 = node { glexeme = FL.fromFL vs }
+                     t2    = fixNode node2 t
+                 return $ EnrSuccess t2 Map.empty
 
 -- | @enrichFeat av fs@ attempts to unify @av@ with @fs@
 --
diff --git a/src/NLP/GenI/LexicalSelection/Types.hs b/src/NLP/GenI/LexicalSelection/Types.hs
--- a/src/NLP/GenI/LexicalSelection/Types.hs
+++ b/src/NLP/GenI/LexicalSelection/Types.hs
@@ -99,7 +99,7 @@
      | SchemaError [Text] LexCombineError2
  deriving Eq
 
-data LexCombineError2 = EnrichError PathEqLhs
+data LexCombineError2 = EnrichError             PathEqLhs
                       | StringError Text
  deriving (Eq, Ord)
 
@@ -111,10 +111,10 @@
  leq _ _ = False
 
 instance Poset LexCombineError2 where
- leq (EnrichError e1) (EnrichError e2)  = leq e1 e2
- leq (EnrichError _ ) (StringError _ )  = True
- leq (StringError s1) (StringError s2)  = leq s1 s2
- leq _ _ = False
+    leq (EnrichError e1) (EnrichError e2)  = leq e1 e2
+    leq (EnrichError _ ) (StringError _ )  = True
+    leq (StringError s1) (StringError s2)  = leq s1 s2
+    leq _ _ = False
 
 instance Poset PathEqLhs where
  leq l1 l2 = leq (showPathEqLhs l1) (showPathEqLhs l2)
