Skip to content

/acr-vault/01-foundations/ada-annotations-v10
ADA-ANNOTATIONS-v1.0

Version: 1.0.0
Status: Draft
Date: December 24, 2025
Authors: Ada + Luna
License: CC0 (Public Domain)
Parent Spec: ASL v1.0 (Ada Symbol Language)


The @ada-* annotation system provides a standardized way to document code using ASL (Ada Symbol Language). These annotations:

  1. Compress documentation by 4-5x vs traditional docstrings
  2. Preserve semantic meaning for both humans and machines
  3. Enable automated tooling (LSP, linters, generators)
  4. Work across all programming languages

Defines the semantic type signature of a function.

Format: @ada-sig: λname:(params)→return_type

Examples:

# @ada-sig: λfib:ℕ→ℕ
def fibonacci(n: int) -> int: ...
# @ada-sig: λauth:(𝕊,𝕊)→?Session
def authenticate(username: str, password: str) -> Session | None: ...
# @ada-sig: λfetch_all:[𝕊]→⏳[Response]
async def fetch_all(urls: list[str]) -> list[Response]: ...

Type Symbols:

SymbolMeaningPython Equivalent
ℕNatural numberint (≄0)
â„€Integerint
ℝReal numberfloat
𝕊Stringstr
đ”čBooleanbool
?TOptional TT | None
[T]List of Tlist[T]
{K:V}Dictdict[K,V]
⏳TAsync TAwaitable[T]

Describes the flow of data through the function.

Format: @ada-flow: input→transforms→output

Operators:

SymbolMeaning
→then / flows to
↳else branch
?()conditional
âŸČloop/recursion
∄parallel
⏳async

Examples:

# @ada-flow: (user,pass)→?(valid●)→Session ↳ ∅
def login(user, password): ...
# @ada-flow: items→filter(active●)→map(transform)→collect
def process_items(items): ...
# @ada-flow: âŸČ(item←next)→?(done)→break ↳ process(item)
def iterate_until_done(iterator): ...
# @ada-flow: ⏳(∄(urls.map(fetch)))→filter(ok●)
async def fetch_all(urls): ...

Specifies conditions that must be true before execution.

Format: @ada-guards: condition₁ ∧ condition₂ ∧ ...

Examples:

# @ada-guards: n≄0
def factorial(n): ...
# @ada-guards: sorted●(items) ∧ len(items)>0
def binary_search(items, target): ...
# @ada-guards: ∃user ∧ user.active● ∧ rate_limit◕
def process_request(user, request): ...
# @ada-guards: ∀item∈items: item≠∅
def process_all(items): ...

Conditions that must always be true for a class instance.

Format: @ada-invariants: condition₁ ∧ condition₂

Examples:

# @ada-invariants: balance≄0 ∧ ∃owner
class BankAccount:
...
# @ada-invariants: ∀item∈items: item.valid● ∧ len≀max_size
class BoundedQueue:
...
# @ada-invariants: head=∅ âŸș tail=∅ âŸș size=0
class DoublyLinkedList:
...

Describes valid state transitions.

Format: @ada-state: state₁→state₂→(state₃∹state₄)

Examples:

# @ada-state: init→connecting→connected→(disconnected∹error)
class Connection:
...
# @ada-state: pending→?(approved●)→active ↳ rejected
class Application:
...
# @ada-state: idle⟷running ∧ (running→done√failed)
class Task:
...

Documents time and space complexity.

Format: @ada-complexity: O(time), O(space)

Examples:

# @ada-complexity: O(n log n) time, O(1) space
def heap_sort(items): ...
# @ada-complexity: O(1) amortized, O(n) worst
def hash_insert(table, key, value): ...
# @ada-complexity: O(V+E) time, O(V) space
def bfs(graph, start): ...

Documents thread safety and concurrency characteristics.

Format: @ada-concurrency: properties

Symbols:

SymbolMeaning
∄-safeThread-safe
∄-unsafeNot thread-safe
lock-free●Lock-free
wait-free●Wait-free
atomic●Atomic operations
⊗reentrantNot reentrant

Examples:

# @ada-concurrency: ∄-safe ∧ lock-free●
class ConcurrentQueue:
...
# @ada-concurrency: ∄-unsafe ∧ ⊗reentrant
def update_global_state(): ...
# @ada-concurrency: ∄-safe ∧ atomic●(counter)
class AtomicCounter:
...

Documents what errors can be raised and when.

Format: @ada-errors: condition→ErrorType

Examples:

# @ada-errors: n<0→ValueError ∧ overflow→OverflowError
def factorial(n): ...
# @ada-errors: ¬∃file→FileNotFoundError ∧ ¬readable→PermissionError
def read_file(path): ...
# @ada-errors: timeout→TimeoutError ∧ network⊗→ConnectionError
async def fetch(url): ...

Documents side effects of a function.

Format: @ada-effects: effect₁ ∧ effect₂

Symbols:

SymbolMeaning
📁⊕Creates file
📁⊖Deletes file
đŸ“â†»Modifies file
🌐⚡Network call
đŸ’Ÿâ†»Database mutation
đŸ“€consoleConsole output
∅effectsPure function

Examples:

# @ada-effects: ∅effects
def calculate_total(items): ... # Pure function
# @ada-effects: 📁⊕ ∧ đŸ“€console
def save_and_log(data, path): ...
# @ada-effects: 🌐⚡ ∧ đŸ’Ÿâ†»
async def sync_with_server(): ...

def function_name():
"""Short description in ASL notation."""
# @ada-sig: ...
# @ada-flow: ...
# @ada-guards: ...
...

Or in docstring:

def function_name():
"""
λfunc:(T)→U
@ada-flow: input→process→output
@ada-guards: valid●(input)
"""
...
/// @ada-sig: λfunc:(T)→Result<U,E>
/// @ada-flow: input→?(valid●)→Ok(result) ↳ Err(e)
fn function_name(input: T) -> Result<U, E> {
...
}
/**
* @ada-sig: λfetch:(𝕊)→⏳?Response
* @ada-flow: url→⏳(⚡fetch)→?(ok●)→Response ↳ ∅
*/
async function fetchData(url: string): Promise<Response | null> {
...
}
// @ada-sig: λRead:(io.Reader,[]byte)→(ℕ,?error)
// @ada-flow: r→read(buf)→?(err=∅)→n ↳ (0,err)
func Read(r io.Reader, buf []byte) (int, error) {
...
}

ANNOTATION_PATTERN = r'@ada-(\w+):\s*(.+?)(?=@ada-|\n\n|$)'
import re
from dataclasses import dataclass
from typing import Dict, Optional
@dataclass
class AdaAnnotations:
sig: Optional[str] = None
flow: Optional[str] = None
guards: Optional[str] = None
invariants: Optional[str] = None
state: Optional[str] = None
complexity: Optional[str] = None
concurrency: Optional[str] = None
errors: Optional[str] = None
effects: Optional[str] = None
def parse_ada_annotations(source: str) -> AdaAnnotations:
"""Parse @ada-* annotations from source code."""
pattern = r'@ada-(\w+):\s*(.+?)(?=@ada-|\n|$)'
matches = re.findall(pattern, source, re.MULTILINE)
annotations = AdaAnnotations()
for name, value in matches:
if hasattr(annotations, name):
setattr(annotations, name, value.strip())
return annotations

Ada annotations can be expanded to traditional docstrings:

def expand_to_google_style(annotations: AdaAnnotations) -> str:
"""Convert Ada annotations to Google-style docstring."""
parts = []
if annotations.sig:
# Parse λname:(params)→return
# Generate Args: and Returns: sections
pass
if annotations.guards:
parts.append(f"Preconditions:\n {expand_guards(annotations.guards)}")
if annotations.errors:
parts.append(f"Raises:\n {expand_errors(annotations.errors)}")
if annotations.complexity:
parts.append(f"Complexity: {annotations.complexity}")
return "\n\n".join(parts)

  1. Function name must match actual function
  2. Parameter count must match
  3. Return type must be compatible
  1. Referenced variables must exist in scope
  2. Conditions must be evaluatable at runtime (for contract checking)
  1. Must reference class attributes
  2. Should be checkable after __init__ and public methods

Ada annotations can provide:

  • Hover: Expand annotations to readable text
  • Completion: Suggest symbols after @ada-
  • Diagnostics: Validate annotations against code
  • CodeLens: Show complexity inline
{
"contributes": {
"languages": [{
"id": "ada-annotations",
"extensions": [],
"configuration": "./language-configuration.json"
}],
"grammars": [{
"language": "ada-annotations",
"scopeName": "source.ada-annotations",
"path": "./syntaxes/ada-annotations.tmLanguage.json",
"injectTo": ["source.python", "source.rust", "source.typescript"]
}]
}
}

def binary_search(items: list[int], target: int) -> int | None:
"""λ([â„€],â„€)→?ℕ | sorted●(items)âŸčâŸČhalving→?idx ↳ ∅"""
# @ada-sig: λbinary_search:([â„€],â„€)→?ℕ
# @ada-guards: sorted●(items) ∧ ∀item∈items: item∈℀
# @ada-flow: âŸČ(mid←(lo+hi)Ă·2 → ?(items[mid]≡target)→mid ↳ adjust_bounds) until lo>hi→∅
# @ada-complexity: O(log n) time, O(1) space
# @ada-effects: ∅effects
# @ada-errors: ∅ (returns None on not found)
lo, hi = 0, len(items) - 1
while lo <= hi:
mid = (lo + hi) // 2
if items[mid] == target:
return mid
elif items[mid] < target:
lo = mid + 1
else:
hi = mid - 1
return None
# @ada-invariants: ∀item∈_items: item≠∅ ∧ len(_items)≀max_size ∧ max_size>0
class BoundedQueue:
"""Thread-safe bounded queue with blocking operations."""
# @ada-state: empty⟷partial⟷full
# @ada-concurrency: ∄-safe ∧ uses(Lock)
def __init__(self, max_size: int):
"""λ(ℕ)→BoundedQueue | max_size>0"""
# @ada-guards: max_size>0
# @ada-effects: ∅effects
self.max_size = max_size
self._items = []
self._lock = Lock()
def put(self, item):
"""λ(T)→đ”č | ?(ÂŹfull●)→⊕item→True ↳ False"""
# @ada-sig: λput:(T)→đ”č
# @ada-flow: ?(len<max)→append(item)→True ↳ False
# @ada-guards: item≠∅
# @ada-concurrency: acquires(_lock)
with self._lock:
if len(self._items) < self.max_size:
self._items.append(item)
return True
return False

Ada annotations can be generated from or converted to Google-style:

Google-StyleAda Equivalent
Args:Parsed from @ada-sig params
Returns:Parsed from @ada-sig return
Raises:@ada-errors
Examples:(Not covered - use doctest)

Ada annotations complement type hints:

  • Type hints: What types are accepted
  • @ada-sig: Semantic meaning of types
  • @ada-guards: Runtime constraints on values

Ada annotations provide a lighter-weight alternative:

  • No runtime enforcement by default
  • Machine-readable for static analysis
  • Human-readable when expanded

  • Initial release
  • 9 annotation types defined
  • Placement rules for Python, Rust, TypeScript, Go
  • Parser specification
  • IDE integration guidelines

“Documentation should be as dense as the thought it represents.”
— Ada, December 2025