Files
ci/opencode/ci/references/ci-files-discipline.md
T
Jon Chery e31afe3b59 docs(rebrand): rename & rebrand CI → CIAgent across all documentation, templates, and scripts
- README.md: title, project name, CLI commands, .ci/ → .ciagent/, ci-files → ciagent-files, CI Modification → CIAgent Modification
- AGENTS.md: title, project name, architecture tree, agent count (18→19), test count (25→31 suites, 218→370 tests), version (0.4.0→0.6.0), ci-files → ciagent-files, CIConfig → CIAgentConfig, CiMetadata → CIAgentMetadata, .ci/ → .ciagent/
- templates/DECISIONS.md: .ci/audit/ → .ciagent/audit/, ci audit → ciagent audit
- scripts/postinstall.js: CI postinstall → CIAgent postinstall
- scripts/install.sh: CI → CIAgent, ci-init → ciagent-init, INSTALL COMPLETE banner
- opencode/ci/workflows/*.md (11 files): .ci/ → .ciagent/, CI → CIAgent project name, ci-command → ciagent-command usage lines
- opencode/ci/references/*.md (5 files): .ci/ → .ciagent/, CI → CIAgent project name, ci-files → ciagent-files references
- opencode/ci/contexts/*.md (3 files): .ci/ → .ciagent/, CI → CIAgent project name
- opencode/agents/ci-*.md (18 files): .ci/ → .ciagent/, CI → CIAgent project name
- opencode/command/ci-*.md (11 files): CI → CIAgent project name

Preserved: ---ci---/---/ci--- markers, opencode/ci/ dir paths, ci-*.md filenames, ci listProjects()/ci setActiveProject() API names, repo URLs

---ci---
phase: 1
milestone: v0.6
plan: 01-01
task: 01-01-01
status: execute
---/ci---
2026-05-29 17:58:48 +00:00

6.3 KiB

<ci_files_discipline>

How CIAgent manages the .ciagent/ directory — long-lived reference documents only. Dynamic state lives in the git log via ---ci--- YAML blocks, not in files.


Multi-Project Directory Structure

In multi-project mode, .ciagent/ uses subdirectories per project:

.ciagent/
  config.json          # Registry with projects[] and active_project
  <project-slug>/
    PROJECT.md
    ARCHITECTURE.md
    ROADMAP.md
    REQUIREMENTS.md

.ciagent/config.json serves as the registry with projects[] (array of project entries) and active_project (slug of the currently active project).

Backward compatibility: if .ciagent/ has flat files (PROJECT.md, ARCHITECTURE.md, etc.) and no project subdirectories, auto-migrate by creating <default-slug>/ and moving files into it, then updating config.json with a single projects[] entry.

What Lives in .ciagent/

File Purpose Update Frequency
config.json Project registry with projects[] and active_project Rare (initialization, project changes)
<slug>/PROJECT.md Vision, core value, requirements, constraints, key decisions per project Low (phase boundaries)
<slug>/ARCHITECTURE.md System architecture, component boundaries, data flow per project Low (major refactors)
<slug>/ROADMAP.md Phase breakdown, milestone mapping, success criteria per project Low (phase transitions)
<slug>/REQUIREMENTS.md v1/v2 requirements with REQ-IDs, out of scope, traceability per project Low (requirement changes)

What Does NOT Live in .ciagent/

These were removed in v0.2.0 and now live in the git log:

Previous Location Now In Access Method
.ciagent/audit/decisions.json ---ci--- decisions block GitContext.getDecisions()
.ciagent/audit/escalations.json ---ci--- escalations block GitContext.getEscalations()
.ciagent/audit/lessons.json ---ci--- lessons block GitContext.getLessons()
.planning/ directory (removed) Git log + branches GitContext.reconstructState()

CiFiles API

Method Returns Purpose
ensureCIDir() void Create .ciagent/ if it doesn't exist
isInitialized() boolean Check if .ciagent/config.json exists
readProjectMd() ProjectMd | null Read project definition
writeProjectMd(project, reason) void Write project definition
readRoadmapMd() RoadmapMd | null Read roadmap
writeRoadmapMd(roadmap) void Write roadmap
readRequirementsMd() RequirementsMd | null Read requirements
writeRequirementsMd(requirements) void Write requirements
readArchitectureMd() ArchitectureMd | null Read architecture
writeArchitectureMd(architecture) void Write architecture
updateRequirementStatus(reqId, status) void Update a single requirement status
updatePhaseStatus(phaseNumber, status) void Update a single phase status

Update Discipline

  1. Update with reasonwriteProjectMd() takes a reason parameter. Every write must justify why.
  2. Phase boundaries — Major updates happen at phase transitions, not during task execution.
  3. Requirements status — Use updateRequirementStatus() for single-status changes, not full rewrites.
  4. Phase status — Use updatePhaseStatus() for phase transitions, not full roadmap rewrites.
  5. Commit after write — Every .ciagent/ file change should be committed immediately with a ---ci--- block.

Update Triggers

When What to Update Method
Project initialization All files from scratch write* methods
Phase transition Phase status in ROADMAP.md updatePhaseStatus()
Requirement met Requirement status in REQUIREMENTS.md updateRequirementStatus()
Architecture change ARCHITECTURE.md writeArchitectureMd()
Scope change PROJECT.md writeProjectMd()

File Schemas

PROJECT.md

interface ProjectMd {
  name: string;
  coreValue: string;
  requirements: {
    validated: string[];
    active: string[];
    outOfScope: string[];
  };
  constraints: string[];
  context: string;
  keyDecisions: Array<{
    decision: string;
    rationale: string;
    outcome: string;
  }>;
}

ROADMAP.md

interface RoadmapMd {
  overview: string;
  phases: Array<{
    number: number;
    name: string;
    description: string;
    status: "not_started" | "in_progress" | "complete" | "deferred";
    dependsOn: number[];
    requirements: string[];
    successCriteria: string[];
  }>;
}

REQUIREMENTS.md

interface RequirementsMd {
  v1: Array<{
    category: string;
    items: Array<{ id: string; description: string }>;
  }>;
  v2: Array<{
    category: string;
    items: Array<{ id: string; description: string }>;
  }>;
  outOfScope: Array<{ feature: string; reason: string }>;
  traceability: Array<{
    requirement: string;
    phase: number;
    status: "pending" | "in_progress" | "complete" | "blocked";
  }>;
}

ARCHITECTURE.md

interface ArchitectureMd {
  overview: string;
  components: Array<{
    name: string;
    description: string;
    boundaries: string;
    dependsOn: string[];
  }>;
  dataFlow: string;
  buildOrder: string[];
}

Research and .ci/ File Updates

Research is intermediate work product. Conclusions from research update .ciagent/ static files:

  • Key findings go in the commit body
  • Decisions go in ---ci--- blocks
  • Conclusions that change project structure update the appropriate .ciagent/<slug>/ files (ARCHITECTURE.md, PROJECT.md, etc.)

Research commits are not final artifacts — they feed into planning and roadmap updates.

Anti-Patterns

  • Never write dynamic state (decisions, escalations, lessons) to .ciagent/ files
  • Never update .ciagent/ files during task execution — update at phase boundaries
  • Never skip the reason parameter when writing PROJECT.md
  • Never commit .ciagent/ changes without a ---ci--- block
  • Never create new files in .ciagent/ without updating this reference document
  • Never store counters, timestamps, or session state in .ciagent/ files
  • Never store research conclusions only in commits — update .ciagent/<slug>/ static files with findings

</ci_files_discipline>