feat(sync): ensure front matter consistency for monorepo specs#844
feat(sync): ensure front matter consistency for monorepo specs#844TimJi wants to merge 2 commits intoFission-AI:mainfrom
Conversation
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
📝 WalkthroughWalkthroughAdded 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
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment 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. |
There was a problem hiding this comment.
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
📒 Files selected for processing (3)
src/core/templates/workflows/archive-change.tssrc/core/templates/workflows/bulk-archive-change.tssrc/core/templates/workflows/sync-specs.ts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
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
📒 Files selected for processing (1)
src/core/templates/workflows/sync-specs.ts
| 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 | ||
|
|
There was a problem hiding this comment.
🧩 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=tsRepository: 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 -A5Repository: 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 -80Repository: 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:
- Add
monorepoAppLabelas an optional boolean field toProjectConfigSchemaand implement the opt-out check in the front matter logic, or - Remove all references to
monorepoAppLabelfrom 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).
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 viaopsx:syncoropsx:archive, newly created specs don't inherit thisconvention — 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
sync-specs.tsarchive-change.tsbulk-archive-change.tsDesign decisions
monorepoAppLabel: falseinopenspec/config.yamlprevents repeated promptsSummary by CodeRabbit