LunarCore Specification
The LunarCore Specification defines shared standards and conventions for all LunarCore SDKs and libraries. This documentation-only repository serves as the source of truth for design decisions, ensuring consistency, predictability, and maintainability across the entire LunarCore ecosystem.
Purpose and Scope
What This Specification Covers
The specification establishes standards for:
- Version numbering and compatibility guarantees
- Logging format and behavior
- Configuration structure and precedence
- Error handling patterns
- Security defaults and practices
- Naming conventions across all languages
What This Specification Does Not Cover
The specification deliberately avoids:
- Language-specific implementation details
- Framework integration patterns
- Application architecture
- Business logic or domain-specific concerns
The focus remains on foundational utilities that every SDK should provide consistently.
Target Audience
This specification is primarily for:
SDK Developers
Those building or maintaining LunarCore libraries across different languages and platforms. The specification ensures their implementations remain consistent with the broader ecosystem.
Integration Engineers
Professionals working across multiple LunarCore SDKs who benefit from consistent behavior and predictable patterns regardless of the underlying technology stack.
Technical Leads
Decision-makers establishing project standards who can reference this specification when setting up new projects or evaluating existing ones.
Contributors
Community members contributing to the LunarCore ecosystem who need to understand the design principles and requirements.
Specification Structure
Numbered Sections
The specification is organized into numbered sections, each covering a specific domain:
- 01 - Versioning: Semantic versioning rules and compatibility guarantees
- 02 - Logging: Log levels, format, and output conventions
- 03 - Configuration: Config structure, loading mechanisms, and precedence rules
- 04 - Error Handling: Error types, messages, and recovery patterns
- 05 - Security: Secrets management, secure defaults, and hardening guidelines
- 06 - Naming Conventions: Variable, function, and module naming standards
Each section can be read independently, though some sections reference others for context.
Identifier System
Every specification item has a unique identifier with the format: LC-XXX-NNN
Where:
LCindicates LunarCoreXXXis the section prefix (VER, LOG, CFG, ERR, SEC, NAM)NNNis the sequential number within that section
Examples:
LC-VER-001: Semantic Versioning requirementLC-LOG-003: Log format specificationLC-ERR-002: Error properties requirement
Why Identifiers Matter
These identifiers serve several purposes:
- Traceability: Implementations can reference specific requirements in comments
- Discussion: Teams can discuss specific rules unambiguously
- Compliance: Deviations can be tracked and documented
- Change Management: Updates to specific requirements can be versioned
Versioning (Section 01)
Semantic Versioning Compliance
All LunarCore SDKs must follow Semantic Versioning 2.0.0 strictly. Version numbers take the form MAJOR.MINOR.PATCH:
- MAJOR version increases indicate breaking changes to the public API
- MINOR version increases add functionality in a backward-compatible manner
- PATCH version increases contain backward-compatible bug fixes
This predictability allows users to upgrade with confidence, knowing exactly what to expect.
Pre-release Versions
Pre-release versions use hyphen notation:
1.0.0-alpha.1: Early development, API may be unstable1.0.0-beta.1: Feature complete, undergoing testing1.0.0-rc.1: Release candidate, production-ready pending feedback
Pre-release versions are explicitly unstable and may introduce breaking changes between increments without a major version bump.
Version Exposure
Every SDK must expose its version number as a constant accessible without instantiation. This enables:
- Runtime version checking
- Compatibility verification
- Debugging version-specific issues
- Automated dependency audits
Deprecation Policy
When deprecating public APIs:
- Mark as deprecated in a MINOR version release
- Keep the API functional with warning logs
- Remove in the next MAJOR version
- Maintain at least one MINOR version cycle before removal
This gives users time to migrate while maintaining backward compatibility.
Compatibility Promise
Within a MAJOR version, all MINOR and PATCH updates are drop-in replacements. This means:
- No changes to function signatures
- No changes to return types or data structures
- No removal of public APIs
- No changes to default behavior affecting existing workflows
Breaking Change Definition
A breaking change is any modification requiring user code changes:
- Removing or renaming public APIs
- Changing function signatures or return types
- Altering default behavior in backwards-incompatible ways
- Changing minimum runtime requirements (e.g., Node.js version)
These changes are only permitted in MAJOR version releases.
Logging (Section 02)
Log Levels
All SDKs must support exactly five log levels:
| Level | Value | Purpose |
|---|---|---|
| ERROR | 50 | System failures requiring immediate attention |
| WARN | 40 | Issues that don't stop execution |
| INFO | 30 | General operational messages |
| DEBUG | 20 | Detailed diagnostic information |
| TRACE | 10 | Very detailed flow information |
The numeric values allow for consistent ordering and filtering across implementations.
Default Level
The default log level must be INFO. This strikes a balance between useful operational information and avoiding excessive noise in production environments.
Log Format
All log messages follow this structure:
[TIMESTAMP] [LEVEL] [COMPONENT] MESSAGE
Example:
[2025-12-22T14:32:11.234Z] [INFO] [LunarCore.Auth] User authenticated successfully
Timestamp Format
Timestamps use ISO 8601 format with millisecond precision and UTC timezone:
YYYY-MM-DDTHH:mm:ss.sssZ
This ensures:
- Unambiguous time representation
- Consistent parsing across systems
- Easy correlation of events across services
Component Naming
Component identifiers must:
- Start with
LunarCore. - Use PascalCase for subcomponents
- Be hierarchical with dots
Examples:
LunarCore.Auth
LunarCore.DB.ConnectionPool
LunarCore.HTTP.Client
Structured Logging
SDKs should support structured logging (JSON output) as an opt-in feature. This enables:
- Machine parsing of logs
- Integration with log aggregation systems
- Advanced filtering and analysis
Sensitive Data Redaction
Certain data types must be automatically redacted in logs:
- Passwords: Replaced with
[REDACTED] - API Keys: Show first 4 characters:
sk-ab...[REDACTED] - Tokens: Show first 8 characters:
eyJhbGci...[REDACTED] - Credit Card Numbers: Never logged
- Personal Identification Numbers: Never logged
This prevents accidental exposure of credentials in log files or monitoring systems.
Configuration (Section 03)
Configuration File Format
SDKs must support configuration in at least one standard format:
- JSON (preferred for simplicity)
- YAML (for complex configurations)
- TOML (for human-friendly syntax)
The choice depends on the ecosystem conventions of the target language.
Default Locations
Configuration files are searched in this order:
- Explicit path provided by user
- Environment variable pointing to config file
- Current working directory
- User home directory
- System-wide configuration directory
Configuration Precedence
When multiple configuration sources exist, they are merged with this precedence (highest to lowest):
- Explicit runtime parameters
- Environment variables
- Configuration file
- Default values
Environment Variable Naming
Environment variables for configuration follow this pattern:
LUNARCORE_[COMPONENT]_[SETTING]
Examples:
LUNARCORE_LOG_LEVEL=debug
LUNARCORE_DB_HOST=localhost
LUNARCORE_HTTP_TIMEOUT=5000
Required vs Optional Settings
Configuration settings must be clearly documented as:
- Required: Application fails to start if missing
- Optional with Default: Uses default value if not provided
- Optional without Default: Feature disabled if not provided
Validation on Load
All configuration must be validated when loaded, not lazily when first used. This ensures:
- Fast feedback on configuration errors
- No surprises during operation
- Clear error messages pointing to the problem
Error Handling (Section 04)
Error Hierarchy
All SDKs must implement a consistent error hierarchy rooted in a base error class:
LunarCoreError
├── ConfigurationError
├── AuthenticationError
├── AuthorizationError
├── ValidationError
├── NetworkError
│ ├── TimeoutError
│ ├── ConnectionError
│ └── RetryExhaustedError
├── ResourceError
│ ├── NotFoundError
│ └── ConflictError
└── InternalError
This consistent structure allows for:
- Type-safe error handling
- Predictable catch blocks
- Common error processing middleware
Error Properties
Every error must include:
name: Error class name (string)message: Human-readable description (string)code: Machine-readable error code (string, format:LC_ERR_XXX)timestamp: When the error occurred (ISO 8601)
Optional but recommended:
context: Additional structured datastatusCode: HTTP status code where applicableisOperational: Whether the error is expected/recoverable
Error Codes
Error codes follow the format: LC_ERR_[CATEGORY]_[NUMBER]
Categories:
AUTH: Authentication errorsAUTHZ: Authorization errorsCFG: Configuration errorsNET: Network errorsVAL: Validation errorsRES: Resource errorsINT: Internal errors
Examples:
LC_ERR_AUTH_001: Invalid API key
LC_ERR_NET_001: Connection timeout
LC_ERR_VAL_001: Invalid parameter type
Error Messages
Error messages must:
- Be clear and actionable
- Include what went wrong
- Suggest how to fix it when possible
- Avoid technical jargon for user-facing errors
- Never expose sensitive data
Good example:
Invalid API key provided. Check your LUNARCORE_API_KEY environment variable.
Bad example:
Error 500
Retryable vs Non-Retryable Errors
Errors should be classified as:
- Retryable: Transient failures that may succeed on retry (network timeouts, service unavailable)
- Non-Retryable: Permanent failures that won't succeed on retry (authentication failures, validation errors)
This classification helps implement smart retry logic.
Security (Section 05)
Secure Defaults
All configuration options must have secure defaults. Never require users to explicitly enable security features.
Examples of secure defaults:
- TLS/SSL enabled for network connections
- Strict input validation enabled
- Sensitive data redaction enabled in logs
- Minimum timeout values that prevent hanging
Secrets Management
Secrets (API keys, passwords, tokens) must:
- Never be hardcoded in application code
- Never be committed to version control
- Be loaded from environment variables or secure vaults
- Be redacted in all logging and error messages
- Use appropriate encryption at rest and in transit
Input Validation
All external input must be validated before processing:
- User-provided data
- Network responses
- File contents
- Environment variables
- Configuration values
Use schema validation libraries rather than manual checks.
Dependency Security
SDKs must:
- Minimize external dependencies
- Keep dependencies up to date
- Regularly scan for known vulnerabilities
- Document security update procedures
- Provide clear upgrade paths for security patches
Cryptography
When cryptographic operations are needed:
- Use well-established libraries (don't roll your own crypto)
- Use current best practices (e.g., TLS 1.2+, modern cipher suites)
- Avoid deprecated algorithms (MD5, SHA1 for security purposes)
- Provide secure random number generation
Naming Conventions (Section 06)
General Principles
Naming should be:
- Descriptive: Names clearly indicate purpose
- Consistent: Similar concepts use similar naming patterns
- Unambiguous: No confusion about what something does
- Idiomatic: Follows language conventions
Language-Specific Conventions
While following the general principles, each SDK should follow its language's conventions:
- JavaScript/TypeScript: camelCase for variables and functions, PascalCase for classes
- Python: snake_case for variables and functions, PascalCase for classes
- Java: camelCase for variables and methods, PascalCase for classes
- C#: PascalCase for methods and properties, camelCase for local variables
Module and Package Naming
Modules follow a hierarchical structure:
@lunarcore/[platform]
dev.lunarbit.lunarcore.[module]
lunarcore.[module]
Function Naming
Functions should:
- Use verbs or verb phrases:
loadConfig,validateInput,createLogger - Be explicit about side effects:
fetch(performs I/O),calculate(pure function) - Follow consistent patterns:
get/set,create/destroy,start/stop
Boolean Properties
Boolean properties should:
- Use question format:
isValid,hasError,shouldRetry - Avoid negative forms: use
isEnabledinstead ofisNotDisabled - Be clearly true/false with no ambiguity
Constants
Constants should:
- Use UPPER_SNAKE_CASE in languages that support it
- Group related constants:
HttpStatus.OK,LogLevel.INFO - Have descriptive names that indicate their purpose
Compliance and Deviations
Striving for Compliance
SDKs should aim for 100% compliance with this specification. The spec represents best practices developed across multiple implementations.
Documenting Deviations
When an SDK must deviate from the spec:
- Document the deviation in the SDK's README
- Explain the reasoning
- Note the specific specification items affected
- Describe the alternative approach taken
Reporting Issues
If a specification requirement is:
- Unclear or ambiguous
- Impractical to implement
- Incompatible with ecosystem conventions
- Missing important cases
Report it to the spec maintainers through GitHub issues for discussion and potential amendment.
Specification Evolution
Stability Guarantee
The specification itself follows semantic versioning:
- Major version changes may introduce breaking changes to spec requirements
- Minor version changes add new requirements in compatible ways
- Patch version changes clarify existing requirements without changing meaning
Change Process
Proposed changes to the specification:
- Start with a GitHub issue for discussion
- Gather feedback from SDK maintainers
- Create a pull request with the proposed changes
- Include impact analysis on existing SDKs
- Merge after consensus
Backwards Compatibility
New specification versions should:
- Avoid invalidating existing conformant implementations
- Provide migration guides for breaking changes
- Allow grace periods for adopting new requirements
Implementation Guidelines
Reference Implementations
The LunarCore Node and LunarCore Fabric SDKs serve as reference implementations. When the specification is ambiguous, these implementations demonstrate the intended behavior.
Testing Compliance
SDKs should include compliance tests that verify specification adherence. This might include:
- Version format validation
- Log output format tests
- Error structure verification
- Configuration precedence tests
Documentation Requirements
Each SDK must document:
- Which specification version it targets
- Any known deviations with justification
- Language-specific adaptations
- Implementation notes for ambiguous cases
Philosophy and Rationale
Why Boring is Good
The specification intentionally favors boring, predictable patterns over clever solutions. This is because:
- Boring is learnable: New contributors can quickly understand the patterns
- Boring is debuggable: Fewer surprises when troubleshooting
- Boring is maintainable: Code is still understandable years later
- Boring is reliable: Well-understood patterns have fewer edge cases
Why Opinionated is Good
The specification makes clear choices rather than offering endless flexibility because:
- Consistency reduces cognitive load
- Fewer choices mean faster development
- Shared patterns enable code reuse
- Clear standards prevent bikeshedding
Why Stable is Good
The specification changes slowly and deliberately because:
- Frequent changes disrupt existing implementations
- Stability builds trust and adoption
- Well-considered changes are better than quick fixes
- Breaking changes are expensive for the entire ecosystem
Use Cases
Cross-Language Projects
Teams building systems with multiple languages benefit from consistent behavior:
- Logs from different services have the same format
- Error codes mean the same thing across services
- Configuration follows the same patterns
SDK Development
When creating a new LunarCore SDK for a different language or platform:
- Start with the specification as requirements
- Reference existing implementations for clarification
- Document any necessary deviations
- Contribute back improvements to the spec
Governance and Standards
Organizations can:
- Adopt the spec as internal standards
- Reference spec requirements in code reviews
- Build tooling to verify compliance
- Contribute organization-specific needs back to the spec
Frequently Asked Questions
Q: Why not use existing standards?
The specification builds on existing standards (ISO 8601, SemVer, etc.) rather than replacing them. It fills gaps specific to the LunarCore ecosystem.
Q: What if my language/platform can't implement a requirement?
Document the deviation and explain why. The spec aims to be practical, not dogmatic. If a requirement is consistently problematic, it may be revised.
Q: How do I propose changes?
Open a GitHub issue describing the problem and proposed solution. Include rationale and impact analysis.
Q: Are there different compliance levels?
No. The goal is full compliance, but documented deviations are acceptable when necessary.
Resources
Specification Documents
- 01 - Versioning
- 02 - Logging
- 03 - Configuration
- 04 - Error Handling
- 05 - Security
- 06 - Naming Conventions
Reference Implementations
Community
License
The LunarCore Specification is released under the MIT License, allowing free use and adaptation with attribution.