This file provides guidance to AI coding assistants when working with this repository.
This is the FinOps Open Cost and Usage Specification (FOCUS) repository - a technical specification for standardizing cloud, SaaS, and billing data schemas. The repository contains both human-readable specification documents (Markdown to HTML/PDF) and machine-readable validation rules (JSON).
FOCUS defines datasets for billing data from cloud providers (AWS, Azure, GCP), SaaS vendors, and on-premises systems. The primary dataset is Cost and Usage, which can be joined with the supplemental Contract Commitment dataset. Key concepts include account hierarchies (billing accounts, sub-accounts, resources) and service hierarchies (categories, names, SKUs). For detailed schema information, read the specification files in specification/.
cd specification
make # Builds spec.md, spec.html, spec.pdf
make STYLE=working_draft # Build as working draft (default)
make STYLE=main # Build as publication version
make STYLE=candidate_release # Build as candidate release
make clean # Clean generated filescd specification/requirements_model
./build_json.py --build-only # Generate model JSON only
./build_json.py # Run tests then generate JSONcd specification/requirements_model
pytest tests/ # Run all requirements model tests
pytest tests/test_schema.py # Run a single test fileLinting is automatically run as part of make. The build will stop if the linter detects issues and will not create the spec.md, spec.html, or spec.pdf files.
To force the build to continue despite linter errors (useful for previewing changes or CI/CD), use:
make force=1To lint individual files:
cd specification
python3 enhanced_markdown_lint.py --config markdownlnt.cfg scan <file.md>Note: The enhanced linter provides contextual error messages showing actual vs expected values.
- Source files:
*.mdand*.mdppfiles inspecification/subdirectories - markdown-pp: Processes
spec.mdpptemplate, resolving!INCLUDEdirectives to assemble the full spec - validate_includes.py: Ensures all
.mdfiles in each directory are included in corresponding.mdpptemplates - pymarkdownlnt: Lints all markdown files
- Pandoc: Converts assembled markdown to HTML with custom filters
- wkhtmltopdf: Generates PDF from HTML
specification/spec.mdpp- Main template that includes all sectionsspecification/datasets/- Supported datasetsspecification/datasets/{dataset}/columns/- Column definitions per datasetspecification/attributes/- Rules that govern datasets, rows, columns, and valuesspecification/metadata/- Dataset metadata schemasspecification/supported_features/- Catalog of FinOps capabilities enabled by FOCUS datasetsspecification/appendix/- Examples and supplementary contentsupporting_content/- Background info from spec development
The specification/requirements_model/ directory contains a machine-readable representation of spec requirements:
model_rules/- JSON files defining validation rules (organized by attributes/, columns/, datasets/)build_json.py- Merges all JSON intobuild/model-<version>.jsontests/- 32+ pytest tests validating rule structure and dependencies
Rule ID Format: <ArtifactName>-<Type>-<NumericId>-<Status>
- Types: C (Column), A (Attribute), D (Dataset)
- Status: M (Mandatory), O (Optional), C (Conditional)
- Example:
ListUnitPrice-C-001-M
AI agents generating or reviewing content MUST act as strict technical editors enforcing the FOCUS standards. Focus entirely on specification documents, schema definitions, and markdown formatting.
- BCP-14 Keywords: Use MUST, MUST NOT, SHOULD, SHOULD NOT, MAY (uppercase). NEVER use: "REQUIRED", "SHALL", "SHALL NOT", "RECOMMENDED", "NOT RECOMMENDED", "OPTIONAL".
- Location: Capitalized keywords MUST NOT appear outside "Requirements" sections unless quoted.
- Structure: Use bulleted lists. Each bullet MUST express exactly one verifiable state. Split bullets that combine multiple obligations.
- Allowed Subjects: MUST be schema-level entities (e.g.,
FOCUS dataset,BilledCost). Actors (e.g., Data Generator) and Processes MUST NOT be subjects. - State vs. Behavior: Describe a state, not behavior. Prohibited process verbs: ensure, handle, support, provide, alter, prefix, document (though they MAY appear in conditional clauses).
- Conditional Phrasing: Use ONLY:
when / unless / only when / except when. (DO NOT useif). - Mathematical Accuracy:
and/oris permitted ONLY in mathematical validations or conditional clauses. - Structural Anchors: Requirements sections MUST begin with a non-verifiable anchor phrase ending in a colon (e.g.,
<Entity> MUST adhere to the following requirements:). - Terminology: Normative text MUST use
ColumnIds, NEVER Display Names. The subject for dataset requirements MUST beFOCUS dataset. Elsewhere, specify the exact abstraction (e.g.,FOCUS dataset,dataset instance,dataset artifact). - Tone: Use formal language. Contractions (e.g., don't, can't) MUST NOT be used in normative requirements.
- Inline Examples: Any non-normative examples embedded within a requirement MUST be enclosed in parentheses using "e.g." (e.g.,
...without lossy transformations (e.g., rounding)).
- Column/Attribute IDs: PascalCase without spaces (e.g., PricingQuantity). Entity IDs MUST be used in normative text sections.
- Column/Attribute Display Names: Normal text with spaces (e.g., "Pricing Quantity"). These SHOULD be used in introductory or explanatory non-normative text.
- No Mixing: Do not mix Entity IDs and Display Names within the same normative requirement.
- Column values: Enclosed in double quotes (e.g.,
"Usage","Tax"). - Glossary terms: Link with
[*term*](#glossary:term)format. - Linking Rule: Link entity names and Glossary terms ONLY on their first occurrence per source file. Exception: Functional links using different anchor text are exempt.
- Lists: All unordered lists MUST use asterisks (
*), never dashes (-) or plus signs (+). Nested bullet points MUST use exactly two spaces per level. - Notes: Important notes must use the blockquote format (
> **Note:**), or> **Preview:**for notes that mark preview content. - Anchors: Pandoc auto-generates custom heading anchors. DO NOT flag missing HTML
<a name="">tags.
- Mathematical & Schema Accuracy: AI reviewers MUST rigorously calculate, parse, and verify all data within examples (especially JSON snippets and tables). Flag any mathematical inconsistencies or hallucinated data.
- JSON Formatting: JSON blocks MUST use double quotation marks for keys. Verify that the JSON is structurally valid.
- Example Disclaimer: Top-level sections with examples and no normative requirements MUST begin with:
> Note: The following section is informative and non-normative. It does not define requirements.Enforce ONLY on Level-2 headings inspec.mdor major section overview files (e.g.,appendix_overview.md). Ignore nested .md files.
- Each section has a
.mdpptemplate that includes individual.mdfiles - All
.mdfiles in a directory must be included in the corresponding.mdpp - Code blocks must be aligned to start of line (not indented)
- Suggestion-first feedback: When a concrete fix exists, post it as a GitHub
suggestionblock so the author can accept with one click. Use plain-text comments only when the feedback requires discussion rather than a specific replacement. - Self-contained comments: Every review comment or suggestion MUST include all context needed for the author to evaluate it independently. Do not reference other comments (e.g., "same as above" or "see my comment on line X").
- Diff-scope discipline: Only flag issues on lines changed or added by the PR. Pre-existing problems are out of scope unless they create a direct inconsistency with new content in the same PR.
- Deduplication: If your tooling can read PR threads, do not flag already-raised issues or post competing suggestions. To add details, reply to the existing thread.
GitHub does not auto-apply templates when issues or PRs are created via API. AI agents MUST include the required template content in the body.
PR bodies MUST complete .github/pull_request_template.md, including the summary, "Type of Change", and "Author Checklist" (with AI Usage Guidelines attestation).
Issue templates are .yml form definitions in .github/ISSUE_TEMPLATE/. Use the correct title prefix and fill all fields marked required in the template.
| Type | Title Prefix | Template |
|---|---|---|
| Action Item | [AI] |
action-item.yml |
| Feature Request | [FR] |
feature-request.yml |
| Feedback | [Feedback] |
feedback.yml |
| Maintenance | [Maintenance] |
maintenance.yml |
| Work Item | [WI] |
work-item.yml |
Per-issue working files are stored in .ai/work/<issue-number>-<kebab-case-name>/:
research.md- Investigation findings and synthesized issue requirementsplan.md- Implementation approachtasks.md- Execution tracking
Naming convention: Use <issue-number>-<kebab-case-name> matching your branch name (e.g., branch 1805-ai-usage-policy → folder .ai/work/1805-ai-usage-policy/).
Fetch issue details from GitHub (gh issue view) rather than saving locally. Summarize relevant requirements into research.md.
These files are committed during active work. After the PR is approved but before merging, delete the working folder. This is a manual step - do not delete working files until final approval is received. Valuable research should be moved to supporting_content/ before approval.
Persistent learnings are stored in .ai/memory/ and are not deleted.
.ai/memory/- Saved context and memory across sessionsspecification/glossary.md- FOCUS terminology definitionsguidelines/- Development processes and conventions
Python packages (in requirements.txt):
- pymarkdownlnt, panflute, watchdog
- pytest, jsonschema (for requirements model tests)
System tools:
- Pandoc (markdown processing)
- wkhtmltopdf (PDF generation)
- GNU Make
AI-assisted contributions are permitted and follow the same review standards as human-authored content. See AI Usage Guidelines for details.