janus doc — Sovereign Documentation
janus doc — Sovereign Documentation
Section titled “janus doc — Sovereign Documentation”Overview
Section titled “Overview”Janus treats documentation as structured, queryable ASTDB data — not opaque text blobs. Every doc comment becomes a columnar row in the semantic database, linked to its target declaration by content ID. Documentation cannot drift from the code it describes because the compiler extracts capabilities, effects, and type signatures directly.
This system is inspired by Elixir’s @doc / ExDoc approach, but goes further:
| Property | Traditional (ExDoc, rustdoc) | Janus Sovereign |
|---|---|---|
| Storage | String blobs attached to AST | ASTDB columnar rows |
| Identity | Name-based (breaks on rename) | CID-based (survives renames) |
| Capabilities | Not tracked | Auto-extracted from compiler EffectsInfo |
| Doctests | Regex-extracted from text | First-class AST nodes, compiled and type-checked |
| Machine-readable | Partial (ad hoc JSON) | Native UTCP + query predicates |
| Incremental | Full rebuild | CID-invalidated (unchanged docs skipped) |
janus doc is the command that reads the ASTDB and generates output in four formats: Markdown, HTML, JSON, and UTCP.
Doc Comment Syntax
Section titled “Doc Comment Syntax”Documentation uses /// line comments placed immediately before a declaration. The compiler captures these as doc_comment trivia tokens during lexing, then a dedicated extraction pass transforms them into structured DocEntry rows in ASTDB.
Full Example
Section titled “Full Example”/// Open a file at the given path.////// @param path Filesystem path to open/// @param mode Access mode (read, write, read_write)/// @param cap Capability token for filesystem access/// @returns File handle bound to the caller's arena/// @error FsError.NotFound Path does not exist/// @error FsError.PermissionDenied Capability insufficient/// @capability CapFsRead Required for read mode/// @since 0.3.0/// @see close_file/// @safety Caller must ensure the capability token outlives the handle./// @complexity O(1) amortized////// ## Examples/// ```janus/// let f = open_file("/data/config.kdl", .read, ctx.cap_fs)/// ```func open_file(path: String, mode: Mode, cap: CapFsRead) -> File ! FsError do // ...endTag Reference
Section titled “Tag Reference”| Tag | Syntax | Purpose |
|---|---|---|
@param | @param name Description | Document a parameter |
@returns | @returns Description | Document return value |
@error | @error ErrorType Description | Document error variant |
@capability | @capability CapName Description | Required capability (supplementary) |
@since | @since version | Version introduced |
@see | @see identifier | Cross-reference to another declaration |
@deprecated | @deprecated Reason | Mark as deprecated with migration guidance |
@safety | @safety Explanation | Safety invariants the caller must uphold |
@complexity | @complexity O(...) | Algorithmic complexity |
Note on @capability: This tag is supplementary. The compiler auto-extracts required capabilities from the function’s EffectsInfo during semantic analysis. Manual @capability tags add human-readable context only. If a manual tag contradicts the compiler’s analysis, a warning is emitted during janus doc --check.
Output Formats
Section titled “Output Formats”Markdown + Mermaid (--format=md)
Section titled “Markdown + Mermaid (--format=md)”janus doc --format=md --output=docs/Generates .md files per module with full Mermaid diagram support:
- Module dependency graphs auto-generated as Mermaid diagrams
- Capability flow diagrams showing token threading
- Compatible with any Markdown renderer (GitHub, GitLab, mdBook, Obsidian)
- Embedded doctest source with pass/fail status annotations
This is the canonical human-readable format. Suitable for version control and rendering alongside source code.
HTML + PicoCSS (--format=html)
Section titled “HTML + PicoCSS (--format=html)”janus doc --format=html --output=site/Generates a static HTML site styled with PicoCSS (classless, ~10KB CSS):
| Feature | Description |
|---|---|
| Module navigation | Hierarchical sidebar mirroring the module tree |
| Mermaid diagrams | Rendered client-side via Mermaid.js |
| Capability badges | Per-function badges showing required capabilities |
| Effect markers | Per-function markers showing tracked effects |
| Symbolic markers | Compiler-derived safety indicators (see Symbolic Markers) |
| Doctest indicators | Embedded source with pass/fail status |
| Cross-references | Clickable links from @see tags |
This is the beautiful browsable format. Intended for hosting on project documentation sites.
JSON (--format=json)
Section titled “JSON (--format=json)”janus doc --format=json --output=api.jsonProduces Canonical JSON (RFC 8785) — deterministic key ordering, no trailing whitespace, signable. Suitable for CI tooling, machine consumption, and registry integration.
This format follows the Law of Representation: KDL is for human intent, JSON is for machine state.
UTCP Manual (--format=utcp)
Section titled “UTCP Manual (--format=utcp)”janus doc --format=utcp --output=manuals/Generates structured JSON formatted for AI agent consumption. Each public declaration gets a UTCP entry containing:
- Function signature with full type annotations
- Parameter descriptions
- Return type and error variants
- Required capabilities and tracked effects
- Embedded examples
This replaces hand-written utcpManual() functions. The compiler generates them from the same ASTDB data.
Documentation Lint (--check)
Section titled “Documentation Lint (--check)”janus doc --checkReports documentation quality issues without generating output:
| Check | Description |
|---|---|
| Undocumented public items | pub declarations missing /// comments |
Missing @param tags | Parameters not documented |
| Capability contradictions | @capability tags that disagree with compiler analysis |
Stale @see references | Cross-references pointing to renamed or removed items |
| Deprecated without reason | @deprecated tags missing migration guidance |
Gate-able in CI: Returns exit code 1 if any issues are found. Combine with HINGE_CI=1 for strict enforcement.
Doctests
Section titled “Doctests”Adjacent Test Blocks
Section titled “Adjacent Test Blocks”Test blocks placed immediately after a function are linked as that function’s doctest. They are first-class AST nodes — compiled, type-checked, and CID-tracked.
/// Clamp a value to a range.func clamp(val: i32, lo: i32, hi: i32) -> i32 do if val < lo do return lo end if val > hi do return hi end return valend
test "clamp basics" do assert(clamp(5, 0, 10) == 5) assert(clamp(-1, 0, 10) == 0) assert(clamp(99, 0, 10) == 10)endThe compiler sees the test block as a child node of clamp in the ASTDB. Renaming clamp updates the link automatically via CID resolution.
Embedded Examples
Section titled “Embedded Examples”Fenced janus code blocks inside doc comments are also treated as doctests:
/// Format a greeting.////// ## Examples/// ```janus/// let msg = greet("Markus")/// assert(msg == "Hello, Markus!")/// ```func greet(name: String) -> String do return "Hello, " ++ name ++ "!"endUnlike regex-extracted doctests in other languages, these are parsed into AST nodes during the doc extraction pass. They participate in type checking and capability analysis.
Running Doctests
Section titled “Running Doctests”janus test --doc # Run all doctestsjanus test --doc --check # Verify they compile without executingCID-based caching ensures unchanged doctests are skipped on subsequent runs. Only modified functions or their transitive dependents trigger re-execution.
Query Predicates
Section titled “Query Predicates”Use janus query --doc to find declarations based on documentation state. This runs a lightweight predicate evaluator against the ASTDB’s DocStore and Decl arrays — no separate index is built.
janus query --doc "func and not has_doc" file.jan # Undocumented functionsjanus query --doc "is_deprecated" file.jan # All deprecated itemsjanus query --doc "func and has_doctest" file.jan # Functions with doctestsjanus query --doc "func and not has_param_doc" file.jan # Missing @param docsjanus query --doc "has_doc and not has_return_doc" file.jan # Missing @returnsPredicate Atoms
Section titled “Predicate Atoms”| Predicate | Meaning |
|---|---|
has_doc | Declaration has a doc entry in DocStore |
is_deprecated | Has @deprecated tag |
has_doctest | Has embedded or adjacent doctest |
has_param_doc | Has at least one @param tag |
has_return_doc | Has @returns tag |
has_error_doc | Has @error tag |
func | Declaration is a function |
struct | Declaration is a struct/type |
enum | Declaration is an enum |
const | Declaration is a constant |
trait | Declaration is a trait |
Combinators
Section titled “Combinators”Combine atoms with and, or, not, and parentheses. Precedence: or < and < not < atom.
janus query --doc "not has_doc" file.jan # All undocumented declarationsjanus query --doc "func and has_doc and not has_param_doc" file.jan # Documented but missing @paramjanus query --doc "func or struct" file.jan # All functions and structsExample Output
Section titled “Example Output”$ janus query --doc "is_deprecated" examples/doc_demo.jan
Doc Query: is_deprecatedFile: examples/doc_demo.jan
line 39: func factorial — deprecated
1 match(es) in 5 declarationsThese predicates operate on the same ASTDB rows that power the documentation output. Queries run against the compiler’s own semantic database.
Symbolic Markers
Section titled “Symbolic Markers”The documentation output includes symbolic markers auto-inserted based on compiler analysis. These are not decorative — they reflect provable properties.
| Symbol | Name | Condition | Meaning |
|---|---|---|---|
⊢ | Turnstile | All doctests pass | Proven — compiler verifies correctness |
⚠ | Hazard | Capabilities required | Effectful — requires capability tokens |
⟁ | Delta | Compiler transforms applied | Transformed — desugared by compiler |
⧉ | Box | Crosses capability boundary | Boundary — context changes at this point |
In HTML output, these appear as colored badges. In Markdown output, they appear inline. In JSON/UTCP output, they are structured fields.
How It Works
Section titled “How It Works”The documentation system is a five-stage pipeline built on top of the existing compilation infrastructure:
-
Lexer captures
///lines asdoc_commenttrivia tokens, preserving their source location and content. -
Doc extraction pass (post-parse, pre-semantic analysis) transforms trivia tokens into structured
DocEntryrows in ASTDB. Each entry contains parsed tags, prose sections, and embedded code blocks. -
CID linking associates each
DocEntrywith its target declaration via content ID. This survives renames, file moves, and refactors — the link is semantic, not textual. -
Compiler enrichment populates capability requirements and effect tracking from the semantic analysis phase’s
EffectsInfo. This data is authoritative — it comes from the compiler, not from human annotation. -
Output generators read the
DocEntrytable and produce the requested format (MD, HTML, JSON, UTCP). Each generator is a standalone module that reads ASTDB and writes files.
Comparison with ExDoc and rustdoc
Section titled “Comparison with ExDoc and rustdoc”| Aspect | ExDoc (Elixir) | rustdoc | Janus Sovereign |
|---|---|---|---|
| Storage | String blobs on module attributes | String blobs in AST | ASTDB columnar rows |
| Identity | Name-based | Name-based | CID-based (rename-proof) |
| Capabilities | Not tracked | Not tracked | Auto-extracted from compiler |
| Doctests | Regex-extracted from Markdown | Regex-extracted from Markdown | First-class AST nodes |
| Machine-readable | JSON via mix docs | Partial (unstable JSON) | Native UTCP + query predicates |
| Incremental | Full rebuild | Full rebuild | CID-invalidated |
| Linting | Basic coverage check | missing_docs lint | Semantic checks including capability contradictions |
| Effect tracking | None | None | Compiler-verified effect annotations |
Implementation Status
Section titled “Implementation Status”| Phase | Description | Status |
|---|---|---|
| Phase 1 | DocEntry/DocTag/DocTest structs in ASTDB | Complete |
| Phase 2 | Doc extraction pass (trivia + decl population) | Complete |
| Phase 3 | janus doc / janus doc --check (MdRenderer + DocChecker) | Complete |
| Phase 4 | janus query --doc predicate evaluator | Complete |
| Phase 5 | Output generators (HTML, JSON, UTCP) | Planned |
| Phase 6 | Doctest execution, auto-extraction, LSP enrichment | Planned |
RFC-025 is complete through Phase 4 (v2026.3.11). The full ASTDB-integrated pipeline is operational: Parser populates trivia and decls, DocExtractor builds DocStore, MdRenderer generates structured Markdown, DocChecker validates coverage, and query predicates search declarations by documentation state.