Skip to content

Latest commit

 

History

History
723 lines (551 loc) · 16.8 KB

File metadata and controls

723 lines (551 loc) · 16.8 KB

Contributing to CodeOSX

Target Audience: This guide is written for AI agents (like Claude) working on the CodeOSX implementation, but is also useful for human developers.


Table of Contents

  1. Development Philosophy
  2. Session Workflow
  3. Task Management
  4. Decision Making
  5. Documentation Requirements
  6. Code Standards
  7. Testing Requirements
  8. Git Workflow
  9. Communication Protocol

Development Philosophy

Core Principles

  1. Compatibility First: Every feature must work on Mac OS X 10.0+ or degrade gracefully
  2. C89 Strict: No C99/C11 features, compile with -std=c89 -pedantic
  3. Document Everything: Decisions, progress, and rationale must be recorded
  4. Test Early: Write tests as you implement, not after
  5. Small Commits: Commit frequently with descriptive messages
  6. No Regressions: All tests must pass before marking a task complete

Development Constraints

  • Binary Size Budget: Final binary must be < 200 KB
  • Memory Budget: Runtime memory < 5 MB under normal operation
  • No Dependencies: Everything bundled (BearSSL, SQLite)
  • Cross-Platform: Code must compile for PowerPC, Intel i386, Intel x86_64

Session Workflow

Every development session should follow this structure:

1. Session Start (5 minutes)

# Check current state
git status
git log --oneline -5

# Review active work
cat Documentation/PROGRESS.md | grep "In Progress"
cat ~/.codeosx/todos.json  # If using TodoWrite tool

Mental Checklist:

  • What phase are we in?
  • What was completed last session?
  • What are the active blockers?
  • What's the goal for this session?

2. Planning (5-10 minutes)

Use the TodoWrite tool to create/update your task list:

[
  {
    "content": "Download and integrate BearSSL 0.6 source",
    "status": "in_progress",
    "activeForm": "Downloading and integrating BearSSL 0.6"
  },
  {
    "content": "Create test_bearssl.c compilation test",
    "status": "pending",
    "activeForm": "Creating test_bearssl.c compilation test"
  },
  {
    "content": "Verify BearSSL compiles with -std=c89",
    "status": "pending",
    "activeForm": "Verifying BearSSL compiles with -std=c89"
  }
]

3. Implementation (1-3 hours)

For each task:

  1. Mark as in_progress in TodoWrite
  2. Implement the feature/fix
  3. Test immediately (unit test or manual verification)
  4. Commit with descriptive message
  5. Mark as completed in TodoWrite

4. Documentation (10-15 minutes)

After completing tasks:

Update PROGRESS.md:

#### Day 3-7: BearSSL Integration
- [x] Download BearSSL 0.6 source
- [x] Add BearSSL as git submodule
- [x] Create test_bearssl.c
- [x] Compile BearSSL on modern Mac (macOS 14+)
- [x] Compile BearSSL with -std=c89 -pedantic ✅ SUCCESS
- [ ] Test on Mac OS X 10.7 Lion (no hardware available)

If you made a decision, update DECISIONS.md:

## 2026-01-16: BearSSL Version Selection

**Decision**: Use BearSSL 0.6 instead of 0.5
**Rationale**:
- Version 0.6 has better TLS 1.2 support
- Compiles cleanly with GCC 4.2 and Clang 15
- Binary size only 18KB (under budget)
**Alternatives Considered**:
- BearSSL 0.5 (older, potentially more compatible with GCC 2.95)
- OpenSSL (too large, ~2MB)
**Trade-offs**: May need patches for very old GCC 2.95 on Mac OS X 10.0
**Testing**: Compiled successfully on macOS 14 with -std=c89 -pedantic
**Status**: Active

5. Session Wrap-Up (5 minutes)

Add session log to PROGRESS.md:

### 2026-01-16: BearSSL Integration Session
- **Duration**: 2 hours
- **Completed**:
  - Downloaded and integrated BearSSL 0.6
  - Created test_bearssl.c
  - Verified C89 compliance
  - Documented BearSSL decision in DECISIONS.md
- **Next Session**: SQLite integration
- **Blockers**: Cannot test on Lion without hardware (accepted risk)

Commit all documentation updates:

git add Documentation/PROGRESS.md Documentation/DECISIONS.md
git commit -m "docs: Update progress and decisions for BearSSL integration"

Task Management

Using TodoWrite Tool

The TodoWrite tool is your primary task tracker during active development.

Task Format:

{
  "content": "Imperative form: 'Create config.c with environment variable loading'",
  "status": "pending|in_progress|completed",
  "activeForm": "Present continuous: 'Creating config.c with environment variable loading'"
}

Rules:

  1. Only ONE task in_progress at a time
  2. Mark completed IMMEDIATELY after finishing (don't batch)
  3. Remove obsolete tasks (don't let list grow stale)
  4. Break large tasks into 2-4 hour chunks

Example Usage:

User: Implement the configuration system

AI Agent:
1. Uses TodoWrite to create task list:
   - Create src/config.h header
   - Create src/config.c implementation
   - Add environment variable parsing
   - Add API key validation
   - Write unit tests
2. Implements each task sequentially
3. Marks completed in TodoWrite as finished
4. Updates PROGRESS.md

Task Breakdown Guidelines

Good Task Size (2-4 hours):

  • "Create config.c with environment variable loading"
  • "Implement read_file tool with path validation"
  • "Write unit tests for JSON parser"

Too Large (needs splitting):

  • "Implement entire HTTP client" → Split into: TLS setup, request building, response parsing
  • "Build all file tools" → One tool at a time

Too Small (combine):

  • "Create config.h" + "Create config.c" → "Implement configuration system"

Decision Making

When to Document Decisions

Document in DECISIONS.md when:

  • Architectural choices: BearSSL vs OpenSSL, SQLite version selection
  • API design: Function signatures, data structures
  • Trade-off decisions: Performance vs compatibility, size vs features
  • Tool/library choices: cJSON vs custom parser
  • Workarounds: Platform-specific hacks

Do NOT document:

  • Obvious implementations (using POSIX file I/O is standard)
  • Temporary debugging changes
  • Minor refactoring without functional impact

Decision-Making Process

1. Identify decision point
   ↓
2. Research options (compile tests, read docs)
   ↓
3. If multiple valid paths → AskUserQuestion
   ↓
4. Make decision (or get user input)
   ↓
5. Document in DECISIONS.md with rationale
   ↓
6. Implement and test
   ↓
7. If fails, revisit decision (update status to "Superseded")

Example: Using AskUserQuestion

When you encounter a decision where user preference matters:

AI Agent: I've researched JSON parser options. We have two good choices:

1. **cJSON** (single-file library)
   - Pros: Mature, well-tested, C89 compatible
   - Cons: ~2000 lines of code, adds ~8KB to binary

2. **Custom minimal parser**
   - Pros: Tiny (~500 lines), only parses what we need
   - Cons: More potential for bugs, need to write tests

Both work on Mac OS X 10.0+. Which would you prefer?

Then use AskUserQuestion tool to present options formally.


Documentation Requirements

Required Documentation

After every significant milestone (completing a phase task):

  1. Update PROGRESS.md:

    • Mark tasks as complete
    • Update completion percentages
    • Add session log entry
  2. Update DECISIONS.md (if applicable):

    • Add decision entry with full template
  3. Update CHANGELOG.md (for releases):

    • Add features/changes under [Unreleased] section
  4. Code Comments:

    • Every function needs a comment (purpose, params, return value)
    • Complex algorithms need explanation
    • Platform-specific hacks need rationale

Documentation Standards

Function Comment Format:

/*
 * Loads configuration from environment variables.
 *
 * Reads ANTHROPIC_API_KEY, CODEOSX_* environment variables and
 * populates the config struct with values or defaults.
 *
 * @param config Pointer to config_t struct to populate
 * @return 0 on success, -1 if API key missing or invalid
 */
int config_load(config_t *config);

File Header Format:

/*
 * config.c - Configuration management for CodeOSX
 *
 * Handles loading environment variables, validating API keys,
 * and setting default values for all configuration options.
 *
 * Compatible with: Mac OS X 10.0+ (C89)
 */

Code Standards

C89 Compliance Checklist

Before committing code, verify:

  • No // comments (use /* */)
  • No variable declarations mid-block
  • No inline functions
  • No long long (use long or cast to double if needed)
  • No for (int i = 0; ...) (declare i at block start)
  • No C99 standard library functions (use POSIX equivalents)
  • Compiles with gcc -std=c89 -pedantic -Wall -Wextra -Werror

Coding Style

Formatting:

  • Indentation: 4 spaces (no tabs)
  • Line length: 100 characters max
  • Braces: K&R style (opening brace on same line)

Naming Conventions:

  • Functions: snake_case (e.g., config_load, http_post_json)
  • Structs: snake_case_t (e.g., config_t, session_t)
  • Constants: UPPER_CASE (e.g., MAX_PATH_LEN)
  • Macros: UPPER_CASE (e.g., ASSERT)

Example:

#define MAX_API_KEY_LEN 256

typedef struct {
    char api_key[MAX_API_KEY_LEN];
    int max_tokens;
} config_t;

int config_load(config_t *config) {
    char *api_key;

    /* Get API key from environment */
    api_key = getenv("ANTHROPIC_API_KEY");
    if (api_key == NULL) {
        return -1;
    }

    /* Copy to config struct */
    strncpy(config->api_key, api_key, MAX_API_KEY_LEN - 1);
    config->api_key[MAX_API_KEY_LEN - 1] = '\0';

    return 0;
}

Error Handling

Always check return values:

/* BAD */
fopen("file.txt", "r");

/* GOOD */
FILE *fp = fopen("file.txt", "r");
if (fp == NULL) {
    fprintf(stderr, "Error: Cannot open file.txt\n");
    return -1;
}

Use consistent error codes:

  • 0 = success
  • -1 = general error
  • -2, -3, etc. = specific error codes (document in header)

Testing Requirements

Test-Driven Development

For every feature:

  1. Write test BEFORE or DURING implementation
  2. Run test to verify it fails (proving it tests something)
  3. Implement feature
  4. Run test to verify it passes
  5. Do NOT mark task complete until test passes

Test Types

Unit Tests (most common):

/* tests/test_config.c */
TEST(config_validate_api_key_valid) {
    ASSERT(config_validate_api_key("sk-ant-test123"),
           "Valid key should pass");
    return 0;
}

TEST(config_validate_api_key_invalid) {
    ASSERT(!config_validate_api_key("invalid"),
           "Invalid key should fail");
    return 0;
}

Integration Tests (shell scripts):

#!/bin/bash
# tests/integration_test.sh

echo "Test 1: Basic API connection"
export ANTHROPIC_API_KEY="sk-ant-test"
timeout 10 ./build/codeosx --test-connection
if [ $? -eq 0 ]; then
    echo "PASS"
else
    echo "FAIL"
    exit 1
fi

Manual Tests (documented in CODEOSX_TESTING.md):

  • Follow manual test checklist
  • Document results in PROGRESS.md

Running Tests

# Build and run unit tests
make tests
./build/test_runner

# Run integration tests
./tests/integration_test.sh

# Verify C89 compliance
make clean
gcc -std=c89 -pedantic -Wall -Wextra -Werror src/**/*.c

Git Workflow

Branch Strategy

  • main - Stable releases only (tagged)
  • develop - Active development (default branch)
  • feature/phase-X-description - Feature branches for major work

Commit Message Format

<type>(<scope>): <subject>

<body>

<footer>

Types:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation only
  • test: Adding or updating tests
  • refactor: Code refactoring
  • style: Formatting changes
  • build: Build system changes

Examples:

feat(http): Add BearSSL TLS 1.2 client

Implemented http_client.c with BearSSL integration.
Supports POST requests to Claude API with custom headers.

Refs: Phase 1, Day 4-10

---

docs(progress): Update Phase 0 completion status

- Marked BearSSL integration as complete
- Added session log for 2026-01-16
- Updated metrics

---

fix(config): Handle missing API key gracefully

Previously crashed with segfault if ANTHROPIC_API_KEY was not set.
Now returns error code -1 with clear error message.

Fixes: Issue #12

Commit Frequency

Commit after:

  • Each completed task (every 1-2 hours)
  • Before switching to a different area of code
  • After all tests pass
  • End of each session

Do NOT:

  • Commit broken code (except on feature branches with WIP prefix)
  • Commit without testing
  • Make massive commits (> 500 lines changed)

Communication Protocol

Asking for Guidance

When uncertain, use this template:

**Context**: I'm implementing [feature] in Phase [X]

**Question**: Should I [option A] or [option B]?

**Option A**: [Description]
- Pros: ...
- Cons: ...

**Option B**: [Description]
- Pros: ...
- Cons: ...

**My Recommendation**: [Choice] because [rationale]

**Impact**: This affects [components/timeline/budget]

Reporting Blockers

When blocked, immediately document:

**Blocker**: [Description]
**Impact**: Cannot proceed with [task/phase]
**Attempted Solutions**:
1. [What you tried]
2. [What you tried]

**Proposed Resolution**:
- Option 1: [Description]
- Option 2: [Description]

**Timeline Impact**: [Estimate delay]

Add to PROGRESS.md under "Active Blockers" section.

Progress Updates

At the end of each session:

  1. Update PROGRESS.md with session log
  2. Inform user of:
    • What was completed
    • What's next
    • Any blockers or decisions needed
  3. Provide metrics:
    • Lines of code written
    • Tests added/passing
    • Binary size (if changed)

Quick Reference

Daily Checklist

Session Start:

  • Review PROGRESS.md
  • Check git status
  • Plan tasks with TodoWrite

During Development:

  • One task in_progress at a time
  • Test each feature immediately
  • Commit every 1-2 hours
  • Update todos as you go

Session End:

  • Mark all completed tasks
  • Update PROGRESS.md
  • Add session log
  • Commit all changes
  • Clean up todos.json

File Update Frequency

  • todos.json: Every task change (real-time)
  • PROGRESS.md: After each milestone or session
  • DECISIONS.md: After architectural decisions
  • CHANGELOG.md: Weekly (under [Unreleased])
  • Code comments: As you write code

Key Commands

# Verify C89 compliance
gcc -std=c89 -pedantic -Wall -Wextra -Werror src/*.c

# Build and test
make clean && make && make test

# Check binary size
ls -lh build/codeosx

# Run connection test
./build/codeosx --test-connection

# View recent progress
tail -20 Documentation/PROGRESS.md

# Check active todos
cat ~/.codeosx/todos.json | jq .

Appendix: Example Session

Full Example: Implementing Configuration System

Session Start:

# Review current state
cat Documentation/PROGRESS.md | grep "Phase 1"
# Shows: Phase 1 - In Progress, need to implement config system

Planning:

// TodoWrite tool
[
  {
    "content": "Create src/config.h with config_t struct",
    "status": "pending",
    "activeForm": "Creating src/config.h with config_t struct"
  },
  {
    "content": "Implement config_load() in src/config.c",
    "status": "pending",
    "activeForm": "Implementing config_load() in src/config.c"
  },
  {
    "content": "Add config_validate_api_key() function",
    "status": "pending",
    "activeForm": "Adding config_validate_api_key() function"
  },
  {
    "content": "Write unit tests in tests/test_config.c",
    "status": "pending",
    "activeForm": "Writing unit tests in tests/test_config.c"
  }
]

Implementation (Task 1):

# Mark in progress
# TodoWrite: Set task 1 to "in_progress"

# Create src/config.h
# (Write config.h with struct definition)

# Verify compiles
gcc -std=c89 -c src/config.h

# Commit
git add src/config.h
git commit -m "feat(config): Add config_t struct definition"

# Mark complete
# TodoWrite: Set task 1 to "completed"

Documentation:

# Update PROGRESS.md
# Mark "Create src/config.h" as [x] done

# No decision needed (standard implementation)

Session Wrap-Up:

### 2026-01-17: Configuration System Implementation
- **Duration**: 2.5 hours
- **Completed**:
  - Created config.h with config_t struct
  - Implemented config_load() with environment variable parsing
  - Added API key validation
  - Wrote 4 unit tests (all passing)
- **Next Session**: HTTP client implementation
- **Blockers**: None

End of Contributing Guide

For questions or clarifications, refer to:

  • CODEOSX_IMPLEMENTATION_PLAN.md - Detailed phase breakdown
  • CODEOSX_ARCHITECTURE.md - System design
  • CODEOSX_TESTING.md - Testing strategies
  • DECISIONS.md - Past decisions and rationale