Skip to content

schema propose --incremental emits create_stem for an already governed empty-inference tree #145

Description

@pablontiv

Description

rootline schema propose --incremental emits a bootstrap-flat / create_stem proposal targeting an already-existing root .stem when the scanned records produce no inferred schema fields. The fixture is governed by a valid version-2 root schema, and every record validates cleanly before proposal generation.

Classification: CLI DEFECT

The documented claim is:

--incremental: skips proposals covered by existing .stem files

Source: .claude/skills/rootline/ref-schema.md:149.

Steps to Reproduce

Reconstruct a clean fixture that reaches real schema resolution and validation:

fixture="$(mktemp -d)"
cat >"$fixture/.stem" <<'YAML'
version: 2
root: true
scope:
  match: "*.md"
schema:
  kind:
    type: enum
    required: false
    values: [note, memo]
YAML
printf '# Alpha\n\nBody only.\n' >"$fixture/a.md"
printf '# Beta\n\nBody only.\n' >"$fixture/b.md"

rootline describe "$fixture" --field schema.kind -o json
rootline validate --all "$fixture" -o json
rootline schema propose --incremental "$fixture" -o json

The describe command proves the existing .stem is resolved as a version-2 schema field:

{"required":false,"severity":"error","source":"<fixture>/.stem","type":"enum","values":["note","memo"]}

Validation reaches the governed records and succeeds:

{"version":2,"kind":"rootline/validate-batch","results":[{"version":1,"kind":"rootline/validate","path":"a.md","valid":true,"errors":[],"warnings":[]},{"version":1,"kind":"rootline/validate","path":"b.md","valid":true,"errors":[],"warnings":[]}],"structural":[],"stem_health":[],"drift_warnings":[],"notices":[],"summary":{"total":2,"valid":2,"invalid":0,"errors_count":0,"warnings_count":0,"drift_warnings_count":0,"structural_errors_count":0,"structural_warnings_count":0,"stem_health_errors_count":0,"stem_health_warnings_count":0,"stem_health_info_count":0}}

The incremental proposal still targets the existing .stem:

{"version":1,"kind":"rootline/schema-proposals","path":"<fixture>","root":"<fixture>","incremental":true,"proposals":[{"id":"bootstrap-flat","operation":"create_stem","target":"<fixture>/.stem","confidence":0.85,"requires_agent":false,"patch":"version: 2\nscope:\n  match: \"*.md\"\nschema:\n","patch_preview":"version: 2\nscope:\n  match: \"*.md\"\nschema:\n"}],"summary":{"total":1,"requires_agent":0,"engine_resolved":1}}

Expected Behavior

proposals is empty or null and summary.total is 0. The records are already governed by the existing valid root .stem, and the generated schema contains no uncovered inferred fields.

Actual Behavior

The command reports one create_stem proposal targeting the .stem that already governs the records. The operation is not applicable without forcing replacement of that existing file.

Why This Matters

Incremental mode cannot be used as a reliable no-op check for already-governed body-only records. Automation sees actionable schema drift where none exists, and the emitted operation targets an existing governance file rather than representing an uncovered inference.

Related Source Evidence

  • cmd/rootline/schema.go:99-103 and cmd/rootline/schema.go:125-126 expose the same incremental coverage contract in CLI help.
  • cmd/rootline/schema.go:583-603 appends bootstrap-flat/create_stem before incremental filtering.
  • cmd/rootline/schema.go:605-617 only runs coverage filtering when schemaToInferences returns at least one inference, so an empty generated schema leaves the pre-appended proposal intact.
  • cmd/rootline/schema.go:622-647 converts an empty generated schema into an empty inference slice.
  • cmd/rootline/schema_test.go:80-142 covers non-empty inferred fields but does not exercise the zero-inference branch.

Related Work

Neither issue covers this symptom.

Environment

  • Rootline version: rootline version 9.12.1
  • OS: macOS
  • Go version: Not applicable, reproduced with the released binary

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingready-for-agentFully specified and ready for an autonomous agent

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions