diff --git a/cartel.cabal b/cartel.cabal
--- a/cartel.cabal
+++ b/cartel.cabal
@@ -3,10 +3,10 @@
 -- http://www.github.com/massysett/cartel
 --
 -- Script name used to generate: genCabal.hs
--- Generated on: 2014-05-28 20:46:01.203146 EDT
+-- Generated on: 2014-05-29 21:17:51.6472 EDT
 -- Cartel library version: 0.6.0.0
 name: cartel
-version: 0.6.0.0
+version: 0.8.0.0
 cabal-version: >= 1.14
 build-type: Simple
 license: BSD3
diff --git a/genCabal.hs b/genCabal.hs
--- a/genCabal.hs
+++ b/genCabal.hs
@@ -49,7 +49,7 @@
 properties :: A.Properties
 properties = A.properties
   { A.prName = "cartel"
-  , A.prVersion = A.Version [0,6,0,0]
+  , A.prVersion = A.Version [0,8,0,0]
   , A.prCabalVersion = (1, 14)
   , A.prBuildType = A.Simple
   , A.prLicense = A.BSD3
diff --git a/lib/Cartel/Ast.hs b/lib/Cartel/Ast.hs
--- a/lib/Cartel/Ast.hs
+++ b/lib/Cartel/Ast.hs
@@ -12,8 +12,63 @@
 --
 -- <http://www.haskell.org/cabal/users-guide/developing-packages.html>
 
-module Cartel.Ast where
+module Cartel.Ast
+  (
+  -- * Constraint trees
+    Logical(..)
+  , Version(..)
+  , Constraint(..)
+  , ConstrTree(..)
 
+  -- * Global package description
+  , BuildType(..)
+  , License(..)
+  , Compiler(..)
+  , Properties(..)
+
+  -- * Repositories
+  , RepoKind(..)
+  , Vcs(..)
+  , Repository(..)
+
+  -- * Flags
+  , Flag(..)
+
+  -- * Build information
+  , Package(..)
+  , Language(..)
+  , BuildInfoField(..)
+
+  -- * Conditionals
+  , Condition(..)
+  , CondTree(..)
+  , CondBlock(..)
+
+  -- * Field class
+  , Field(..)
+
+  -- * Libraries
+  , LibraryField(..)
+  , Library(..)
+
+  -- * Executables
+  , ExecutableField(..)
+  , Executable(..)
+
+  -- * Test suites
+  , TestSuiteType(..)
+  , TestSuiteField(..)
+  , TestSuite(..)
+
+  -- * Benchmarks
+  , BenchmarkField(..)
+  , Benchmark(..)
+
+  -- * Cabal
+  , Cabal(..)
+
+  ) where
+
 -- | A version number.  The Cabal documentation says this
 -- \"usually\" consists of a sequence of natural numbers separated
 -- by dots.  Though this suggests that a version number could
@@ -253,15 +308,14 @@
 
 -- | What kind of test suite is this?
 data TestSuiteType
-  = ExitcodeStdio String
+  = ExitcodeStdio
   -- ^ An @exitcode-stdio-1.0@ test.  The @String@ is the name of
-  -- the file containing the executable code.  This @String@ becomes
-  -- the @main-is@ is the resulting Cabal file.
+  -- the file containing the executable code.  In this case, the
+  -- 'TestMainIs' field is required.
 
-  | Detailed String
-  -- ^ The @detailed-1.0@ test.  The @String@ is the module
-  -- exporting the @tests@ symbol.  The @String@ becomes the
-  -- @test-module@ field in the resulting Cabal file.
+  | Detailed
+  -- ^ The @detailed-1.0@ test.  In this case, the 'TestModule'
+  -- field is required.
   deriving (Eq, Ord, Show)
 
 -- | A single field value in a test suite section.  A single test
@@ -269,10 +323,26 @@
 data TestSuiteField
   = TestType TestSuiteType
   -- ^ What kind of test this is
+
+  | TestMainIs String
+  -- ^ The name of the @.hs@ or @.lhs@ file containing the @Main@
+  -- module.  The @.hs@ filename must be listed, even if that file
+  -- is generated with a preprocessor.  The file must be relatie to
+  -- one of the directories listed in 'HsSourceDirs'.  This field
+  -- is required when using 'ExitcodeStdio' and disallowed when
+  -- using 'Detailed'.
+
+  | TestModule String
+  -- ^ The module exporting the @tests@ symbol.  This field is
+  -- required when using 'Detailed' and disallowed when using
+  -- 'ExitcodeStdio'.
+
   | TestConditional (CondBlock TestSuiteField)
   -- ^ A test may contain zero or more conditional blocks.
+
   | TestInfo BuildInfoField
   -- ^ A test suite can contain build information fields.
+
   deriving (Eq, Ord, Show)
 
 instance Field TestSuiteField where
@@ -525,6 +595,7 @@
 
   } deriving (Eq, Ord, Show)
 
+-- | Data for the entire Cabal file.
 data Cabal = Cabal
   { cProperties :: Properties
   , cRepositories :: [Repository]
diff --git a/lib/Cartel/Defaults.hs b/lib/Cartel/Defaults.hs
--- a/lib/Cartel/Defaults.hs
+++ b/lib/Cartel/Defaults.hs
@@ -7,6 +7,11 @@
 
 import qualified Cartel.Ast as A
 
+-- | A default 'A.Properties'.  'A.prCabalVersion' is @(1, 14)@ to
+-- specify Cabal version 1.14; 'A.prBuildType' is 'A.Simple', and
+-- 'A.prLicense' is 'A.BSD3'.  All other items are either the empty
+-- 'String' or the empty list, including the 'A.prVersion', which is
+-- left empty.
 properties :: A.Properties
 properties = A.Properties
   { A.prName = ""
@@ -34,6 +39,8 @@
   , A.prExtraTmpFiles = []
   }
 
+-- | A default 'A.Cabal'.  'properties' is used for 'A.cProperties',
+-- and 'A.cLibrary' is 'Nothing'; all other lists are empty.
 cabal :: A.Cabal
 cabal = A.Cabal
   { A.cProperties = properties
@@ -45,6 +52,10 @@
   , A.cBenchmarks = []
   }
 
+-- | A default 'A.Repository'.  You must supply the VCS type,
+-- information about the kind of repository ('A.Head' or 'A.This'),
+-- and the repository location.  'A.repoBranch' and 'A.repoSubdir'
+-- are empty.
 repository
   :: A.Vcs
   -- ^ Type of VCS in use
@@ -64,3 +75,12 @@
   , A.repoSubdir = ""
   }
 
+-- | A default 'A.Flag'.  'A.flName' and 'A.flDescription' are
+-- empty; 'A.flDefault' is 'True', and 'A.flManual' is 'False'.
+flag :: A.Flag
+flag = A.Flag
+  { A.flName = ""
+  , A.flDescription = ""
+  , A.flDefault = True
+  , A.flManual = False
+  }
diff --git a/lib/Cartel/Render.hs b/lib/Cartel/Render.hs
--- a/lib/Cartel/Render.hs
+++ b/lib/Cartel/Render.hs
@@ -171,12 +171,14 @@
 
 testSuiteType :: A.TestSuiteType -> String
 testSuiteType t = case t of
-  A.ExitcodeStdio _ -> "exitcode-stdio-1.0"
-  A.Detailed _ -> "detailed-1.0"
+  A.ExitcodeStdio -> "exitcode-stdio-1.0"
+  A.Detailed -> "detailed-1.0"
 
 instance Field A.TestSuiteField where
   field i t = case t of
     A.TestType a -> labeled i "type" (testSuiteType a)
+    A.TestMainIs s -> labeled i "main-is" s
+    A.TestModule s -> labeled i "test-module" s
     A.TestConditional b -> condBlock i b
     A.TestInfo b -> field i b
 
