Skip to content

feat(sync): ensure front matter consistency for monorepo specs#844

Open
TimJi wants to merge 2 commits intoFission-AI:mainfrom
TimJi:feat/monorepo-spec-frontmatter
Open

feat(sync): ensure front matter consistency for monorepo specs#844
TimJi wants to merge 2 commits intoFission-AI:mainfrom
TimJi:feat/monorepo-spec-frontmatter

Conversation

@TimJi
Copy link

@TimJi TimJi commented Mar 16, 2026

Problem

In monorepo projects, specs need YAML front matter (e.g., app: web-dashboard, app: api-server) to indicate which app/package they belong to. When syncing delta specs to main specs via opsx:sync or opsx:archive, newly created specs don't inherit this
convention — leading to inconsistent specs that are missing their app label.

Solution

Add a front matter consistency step (step 3e) to the sync workflow. After syncing, it checks whether existing main specs use front matter and applies the same pattern to newly synced specs.

Decision flow:

openspec/config.yaml has monorepoAppLabel: false?
→ skip (user opted out)

Existing specs have front matter?
→ yes: apply same pattern to new specs
→ no + single-app project: skip
→ no + monorepo detected: prompt user
→ "Establish convention": apply app: , future syncs auto-detect
→ "Skip and don't ask again": write monorepoAppLabel: false to config.yaml

Changes

File Change
sync-specs.ts Step 3e: full front matter consistency logic (both skill + command templates)
archive-change.ts Reference sync step 3e after sync (both skill + command templates)
bulk-archive-change.ts Reference sync step 3e after sync (both skill + command templates)

Design decisions

  • Logic lives in sync only — archive and bulk-archive reference it, avoiding duplication
  • Convention-based, not prescriptive — samples existing specs to detect the pattern rather than hardcoding a specific front matter schema
  • Opt-out is persistentmonorepoAppLabel: false in openspec/config.yaml prevents repeated prompts
  • Single-app projects are unaffected — skips entirely when no monorepo is detected

Summary by CodeRabbit

  • Improvements
    • Added automatic front-matter consistency during spec synchronization. Newly synced specs will align with existing front-matter conventions, with options to establish or opt out of an app-label convention via project settings. Monorepo and single-app scenarios are handled differently to minimize manual edits.

@TimJi TimJi requested a review from TabishB as a code owner March 16, 2026 03:00
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 16, 2026

📝 Walkthrough

Walkthrough

Added a new "Ensure front matter consistency" step to the sync-specs workflow templates and inserted references to that step in the archive-change and bulk-archive-change workflow templates. Changes document when and how front matter should be applied for newly synced specs (monorepo handling, opt-out flag).

Changes

Cohort / File(s) Summary
Sync-specs workflow templates
src/core/templates/workflows/sync-specs.ts
Inserted a new step "e. Ensure front matter consistency" into both getSyncSpecsSkillTemplate and getOpsxSyncCommandTemplate; defines monorepoAppLabel opt-out, detection of existing front matter patterns, single-app vs monorepo prompts, and actions to apply or skip app labels.
Archive workflow templates
src/core/templates/workflows/archive-change.ts, src/core/templates/workflows/bulk-archive-change.ts
Added brief notes after sync steps instructing to ensure front matter consistency on newly synced specs and referencing the sync-specs step for full logic.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • TabishB

Poem

🐰 I hop through specs with gentle care,
Front matter neat, I tuck it there,
Monorepo or single, I ask and then apply,
Tiny labels snug — no need to cry! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately captures the main feature: adding front matter consistency checks for monorepo specs in the sync workflow across three template files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can use TruffleHog to scan for secrets in your code with verification capabilities.

Add a TruffleHog config file (e.g. trufflehog-config.yml, trufflehog.yml) to your project to customize detectors and scanning behavior. The tool runs only when a config file is present.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/core/templates/workflows/sync-specs.ts`:
- Around line 75-76: Replace hardcoded "openspec/config.yaml" writes in the
sync-specs template with logic that detects and updates the repo's existing
config file extension (.yml or .yaml) instead of creating a new file; locate the
string occurrences "openspec/config.yaml" in
src/core/templates/workflows/sync-specs.ts (both template blocks) and change the
template to determine the existing file name (check for openspec/config.yml
first, then openspec/config.yaml) and write updates to that discovered filename
(fall back to the repo's prevailing convention if neither exists). Ensure both
template blocks use the same configFileName variable so the opt-out update and
any other writes modify the existing config file in place rather than creating a
second file.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ff6741d8-bace-4e99-b089-652b9245eb45

📥 Commits

Reviewing files that changed from the base of the PR and between afdca0d and a74345f.

📒 Files selected for processing (3)
  • src/core/templates/workflows/archive-change.ts
  • src/core/templates/workflows/bulk-archive-change.ts
  • src/core/templates/workflows/sync-specs.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/core/templates/workflows/sync-specs.ts`:
- Around line 74-84: The template references a non-existent opt-out config field
monorepoAppLabel which is not part of ProjectConfigSchema and is ignored by
readProjectConfig(); fix by either (A) fully implementing the opt-out: add
monorepoAppLabel?: boolean to ProjectConfigSchema, update readProjectConfig() to
parse and return it via the ProjectConfig type, and then use that returned value
in the front-matter logic in sync-specs.ts (and archive-change.ts) where
monorepoAppLabel is currently checked; or (B) remove all monorepoAppLabel
references from sync-specs.ts and archive-change.ts and update the template text
to use an alternative opt-out (e.g., a flag file or CLI option) instead—choose
one approach and make consistent changes to the ProjectConfig type,
readProjectConfig(), and the front-matter prompt/logic (symbols to update:
ProjectConfigSchema, readProjectConfig, ProjectConfig type, and the
monorepoAppLabel checks in sync-specs.ts / archive-change.ts).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7c5ebdba-f1fb-49f5-8fae-86f67c192e14

📥 Commits

Reviewing files that changed from the base of the PR and between a74345f and fcd8f50.

📒 Files selected for processing (1)
  • src/core/templates/workflows/sync-specs.ts

Comment on lines +74 to +84
e. **Ensure front matter consistency** on newly synced specs (common in monorepos where specs need to indicate which app/package they belong to):
- If the project config (\`openspec/config.yaml\` or \`openspec/config.yml\`) contains \`monorepoAppLabel: false\` → skip
- Sample existing main specs in \`openspec/specs/\` for YAML front matter convention
- If existing specs use front matter → apply same pattern to newly created/updated specs
- If no existing specs have front matter AND project is single-app → skip
- If no existing specs have front matter AND project is a monorepo (multiple apps/packages detected):

**Prompt options:**
- "Establish front matter convention (recommended)" — suggest \`app: <name>\` based on project structure, apply to newly synced specs
- "Skip and don't ask again" — add \`monorepoAppLabel: false\` to the existing OpenSpec config file without overwriting other keys

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how ProjectConfigSchema handles unknown fields (strict vs passthrough)
rg -nC5 'ProjectConfigSchema' --type=ts

# Check if there's any existing handling for monorepoAppLabel
rg -n 'monorepoAppLabel' --type=ts

Repository: Fission-AI/OpenSpec

Length of output: 2650


🏁 Script executed:

# Search for where monorepoAppLabel is being read/accessed
rg -n 'monorepoAppLabel' --type=ts -A2 -B2

# Also check if there's any special config parsing logic
rg -n 'parseProjectConfig|readConfig' --type=ts -A5

Repository: Fission-AI/OpenSpec

Length of output: 6452


🏁 Script executed:

# Look at the full project-config.ts file to see config reading logic
cat -n src/core/project-config.ts

# Search for where ProjectConfig is actually used/accessed
rg -n 'ProjectConfig\b' --type=ts -B2 -A2 | head -80

Repository: Fission-AI/OpenSpec

Length of output: 15828


Remove references to monorepoAppLabel config field or implement the feature properly.

The template instructs adding monorepoAppLabel: false to the config file as an opt-out mechanism, but this field is not part of ProjectConfigSchema and is never read by readProjectConfig(). The parsing logic (lines 66-161 of src/core/project-config.ts) explicitly extracts only schema, context, and rules fields; any other fields in the YAML are silently ignored.

This means the described opt-out feature does not work. Either:

  1. Add monorepoAppLabel as an optional boolean field to ProjectConfigSchema and implement the opt-out check in the front matter logic, or
  2. Remove all references to monorepoAppLabel from the template instructions and use a different opt-out mechanism (e.g., a dedicated flag file or command-line option)

Current references appear in lines 75, 83, 225, 233 of sync-specs.ts and related instructions in archive-change.ts.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/templates/workflows/sync-specs.ts` around lines 74 - 84, The
template references a non-existent opt-out config field monorepoAppLabel which
is not part of ProjectConfigSchema and is ignored by readProjectConfig(); fix by
either (A) fully implementing the opt-out: add monorepoAppLabel?: boolean to
ProjectConfigSchema, update readProjectConfig() to parse and return it via the
ProjectConfig type, and then use that returned value in the front-matter logic
in sync-specs.ts (and archive-change.ts) where monorepoAppLabel is currently
checked; or (B) remove all monorepoAppLabel references from sync-specs.ts and
archive-change.ts and update the template text to use an alternative opt-out
(e.g., a flag file or CLI option) instead—choose one approach and make
consistent changes to the ProjectConfig type, readProjectConfig(), and the
front-matter prompt/logic (symbols to update: ProjectConfigSchema,
readProjectConfig, ProjectConfig type, and the monorepoAppLabel checks in
sync-specs.ts / archive-change.ts).

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.

1 participant