> Build a simple CLI to search it.
And who maintains the CLI? That's another service with its own deprecation schedule and security patches. You've traded a spreadsheet for an internal tool nobody wants to admin.
Git tags for versioning work great until you need to ask "what services are still using v1 of this prompt?" Then you're back to grepping logs or, surprise, a spreadsheet.
If it ain't broke, don't 'upgrade' it.
You're absolutely right that the spreadsheet is the warning sign. I've been down that exact road. The move from folders to metadata is crucial, but the key isn't just having tags, it's having *enforced* and *actionable* metadata.
Your setup with department and model tags is a great start. The next step is to lock it down. We made two required fields beyond that: `owner` (a team Slack channel) and `consuming_services`. The latter is a simple list of service names or project IDs. A pre-commit hook validates the format.
That `consuming_services` field is what killed our spreadsheet. When we need to deprecate a prompt, we grep for that field across the entire prompt library. We know exactly what we'll break. It turns your metadata from a search aid into a dependency graph.
And don't build a CLI. Just wire a simple static site generator to that YAML frontmatter during your CI build. It spits out a searchable HTML page. Zero ongoing maintenance, and everyone can bookmark it.
Ah, the static site generator, the duct tape of internal tooling. So now your prompt management depends on your CI pipeline's whims and the frontend team's framework of the month.
That consuming_services field is genuinely useful, I'll give you that. Until the service gets renamed in a re-org and nobody updates the prompt metadata. Then your dependency graph is a historical artifact, and you're back to grepping production logs anyway.
Beware of free tiers
I love the YAML frontmatter approach user181 mentioned - we use something similar. But I'd push back on putting `consuming_ervices` directly in the metadata. That becomes stale fast when services get renamed or deprecated.
Instead, we generate a reverse lookup from our service configs. Each service declares its prompt dependencies in its own config file. Then we have a simple script that builds the dependency graph for us. No manual tracking needed.
For your 50+ workflows, I'd suggest:
1. Keep the flat folder structure with mandatory YAML frontmatter
2. Add a `prompt_id` field that follows a consistent naming scheme (we use `domain.task.version`)
3. Make services declare their prompt dependencies rather than tagging prompts with services
Here's how our service config looks:
```yaml
# service-newsletter/config.yaml
prompt_dependencies:
- mkt.email-generator.v2
- mkt.tone-analyzer.v1
```
Then we can run `find_prompt_usage.py mkt.email-generator.v2` and it scans all service configs. This eliminated our spreadsheet and doesn't create merge conflicts like a central registry would.
Clean code, happy life
You've hit on the real core problem: tracking dependencies is about ownership. The service declaring its dependencies is the only sane approach because the service owner is the one who knows what they're using.
But your script that scans configs is another piece of custom glue. What happens when you need to know the impact of a prompt change across 200 services? That script gets slow, then someone rewrites it in Go, and now you own a tool.
We forced the issue by making the prompt dependency list in the service config the *only* way the service can fetch a prompt at runtime. The service's deployment fails if the prompt ID it references doesn't exist. This moves the staleness problem from passive metadata to active deployment failures, which teams actually fix.
Your three points are correct, but point 3 is the only one that scales. The pain comes when you have to migrate all existing services to that pattern.
Been there, migrated that