---ci---
project: ci
phase: 1
milestone: v0.5
status: complete
decisions:
- id: D-020
decision: Phase 1 Quick Wins complete
rationale: All 5 FIX requirements (FIX-01 through FIX-05) verified and passing
confidence: 0.95
alternatives: []
requirements:
covered: [FIX-01, FIX-02, FIX-03, FIX-04, FIX-05]
---/ci---
Phase 1 (Quick Wins) summary:
- A1/FIX-01: Marked .planning/ refs as (legacy)/(removed) in docs
- A2/FIX-02: Removed unused execSync import from ollama-base.ts
- A3/FIX-03: Replaced postinstall with explicit install-opencode, removed scripts/ from files
- A4/FIX-04: Verified opencode.json is clean (no learnship entry)
- A5/FIX-05: Version bump to 0.5.0
6.2 KiB
<ci_files_discipline>
How CI manages the .ci/ 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, .ci/ uses subdirectories per project:
.ci/
config.json # Registry with projects[] and active_project
<project-slug>/
PROJECT.md
ARCHITECTURE.md
ROADMAP.md
REQUIREMENTS.md
.ci/config.json serves as the registry with projects[] (array of project entries) and active_project (slug of the currently active project).
Backward compatibility: if .ci/ 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 .ci/
| 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 .ci/
These were removed in v0.2.0 and now live in the git log:
| Previous Location | Now In | Access Method |
|---|---|---|
.ci/audit/decisions.json |
---ci--- decisions block |
GitContext.getDecisions() |
.ci/audit/escalations.json |
---ci--- escalations block |
GitContext.getEscalations() |
.ci/audit/lessons.json |
---ci--- lessons block |
GitContext.getLessons() |
.planning/ directory (removed) |
Git log + branches | GitContext.reconstructState() |
CiFiles API
| Method | Returns | Purpose |
|---|---|---|
ensureCIDir() |
void | Create .ci/ if it doesn't exist |
isInitialized() |
boolean | Check if .ci/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
- Update with reason —
writeProjectMd()takes areasonparameter. Every write must justify why. - Phase boundaries — Major updates happen at phase transitions, not during task execution.
- Requirements status — Use
updateRequirementStatus()for single-status changes, not full rewrites. - Phase status — Use
updatePhaseStatus()for phase transitions, not full roadmap rewrites. - Commit after write — Every
.ci/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 .ci/ static files:
- Key findings go in the commit body
- Decisions go in
---ci---blocks - Conclusions that change project structure update the appropriate
.ci/<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
.ci/files - Never update
.ci/files during task execution — update at phase boundaries - Never skip the
reasonparameter when writing PROJECT.md - Never commit
.ci/changes without a---ci---block - Never create new files in
.ci/without updating this reference document - Never store counters, timestamps, or session state in
.ci/files - Never store research conclusions only in commits — update
.ci/<slug>/static files with findings
</ci_files_discipline>