Paragraph? in NodeSpec content and <Enter> gives unintended behavior

I’m doing a little ProseMirror + Gherkin mashup. Given these two slices of schema:

    export const feature: NodeSpec = {
      content: 'feature_title paragraph? (rule | scenario)+',
      attrs: {
        id: { default: '' },
      },
      group: 'block features',
      selectable: false,
      parseDOM: [
        {
          tag: 'feature',
        },
      ],
      toDOM: node => {
        const featureNode = node as FeatureNode

        const { id } = featureNode.attrs

            return ['feature', { id }, 0]
      },
    }

and

    export const rule: NodeSpec = {
      content: 'rule_title paragraph? scenario+',
      attrs: {
        id: { default: '' },
        placeholder: { default: '' }, 
      },
      group: 'block element',
      selectable: false,
      parseDOM: [
        {
          tag: 'feature-rule',
          getAttrs: r => {
            const dom = r as HTMLElement

            const attrs: Partial<Attrs> = {
              id: dom.getAttribute('id') || undefined,
            }

            const placeholder = dom.getAttribute('data-placeholder-text')

            if (placeholder) {
              attrs.placeholder = placeholder
            }

            return attrs
          },
        },
      ],
      toDOM: node => {
        const ruleNode = node as RuleNode

        const attrs: { [key: string]: string } = {}

        if (ruleNode.attrs.id) {
          attrs.id = ruleNode.attrs.id
        }

        attrs.class = 'block'

        attrs['data-object-type'] = "rule"

        if (ruleNode.attrs.placeholder) {
          attrs['data-placeholder-text'] = ruleNode.attrs.placeholder
        }

        return ['feature-rule', attrs, 0]
      },
    }

When I insert a node of type ‘feature’, I get the expected empty feature -> rule -> scenario structure in the dom. When I type in the feature title then hit <enter>, a paragraph node is added (not by me?). When I hit <Enter> after typing the optional paragraph, the cursor sticks at the end of the paragraph. I have to click into the rule to set the rule title, and get the same unwanted behavior at the end of the optional paragraph.

What do I have messed up in my schema for “0 or 1” behavior and the <Enter> key after 1 item is present?

The default behavior of the splitBlock command, which is probably bound to Enter, is, when you are at the end of the current textblock, to create a new textblock of the first valid type it finds after your current textblock. In your schema that would be a paragraph.

You can bind a custom command to Enter with higher priority, and make it take effect in the situations where you want something else to happen.

Nothing. The schema looks fine. It’s just not possible to define default commands for complicated things like Enter that work for all possible schemas, so when you move away from a simple block structure you’ll have to do some more scripting to make such keys work the way you want.