Skip to content

Commit a9b4fba

Browse files
Merge pull request #68 from foundersandcoders/feat/final-fac-build
Final FaC Build: Automated Releases & Roadmap Archiving
2 parents dfa10fc + 22dbf04 commit a9b4fba

11 files changed

Lines changed: 109 additions & 136 deletions

File tree

.claude/CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,6 @@ This project uses automated evidence tracking via git hooks. Every commit with K
228228

229229
## Getting Help
230230
- **Claude Code:** Use `/project/init` to reconfigure
231-
- **Roadmaps:** See `docs/roadmaps/` (restructured into 3 phases: [Phase 1](docs/roadmaps/phase-1-mvp-features.md), [Phase 2](docs/roadmaps/phase-2-production-features.md), [Phase 3](docs/roadmaps/phase-3-future-features.md))
231+
- **Roadmaps:** See `docs/roadmaps/` (archived into 3 phases: [Phase 1](docs/roadmaps/archive/2026/01/phase-1-mvp-features.md), [Phase 2](docs/roadmaps/archive/2026/01/phase-2-production-features.md), [Phase 3](docs/roadmaps/archive/2026/01/phase-3-future-features.md))
232232
- **Architecture:** See `docs/adrs/`
233233
- **Technical details:** See `docs/technical/`

.github/release.yml

Lines changed: 0 additions & 81 deletions
This file was deleted.

.github/workflows/release.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Credit to Bad Echo - https://github.com/BadEcho/.github/blob/master/workflow-templates/release.yml
2+
name: Build and Release Iris TUI
3+
4+
on:
5+
push:
6+
tags:
7+
- "v*" # fires on: git tag v5.1.0 && git push --tags
8+
9+
jobs:
10+
build-macos:
11+
name: Build macOS binary
12+
runs-on: macos-latest
13+
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Bun
19+
uses: oven-sh/setup-bun@v2
20+
with:
21+
bun-version: latest
22+
23+
- name: Install dependencies
24+
run: bun install --frozen-lockfile
25+
26+
- name: Build TUI binary (Apple Silicon)
27+
run: bun run build:tui:mac
28+
# Outputs: dist/iris-darwin-arm64
29+
30+
- name: Verify binary
31+
run: dist/iris-darwin-arm64 help
32+
33+
- name: Create GitHub Release and upload asset
34+
uses: softprops/action-gh-release@v2
35+
with:
36+
files: dist/iris-darwin-arm64
37+
generate_release_notes: true
38+
env:
39+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Iris `v5.0.0`
1+
# Iris `v5.1.0`
22

33
**ILR toolkit for apprenticeship data submission**
44

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,4 @@ The MVP development has been split into three distinct phases:
6767
## Archive
6868

6969
The original combined roadmap (pre-restructure) has been archived at:
70-
[`docs/archive/mvp-original.md`](../archive/mvp-original.md)
70+
[`docs/archive/mvp-original.md`](../../../../archive/mvp-original.md)

docs/roadmaps/2026-q1/phase-1-mvp-features.md renamed to docs/roadmaps/archive/2026/01/phase-1-mvp-features.md

Lines changed: 47 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
# Phase 1: MVP Features
22

3-
| Sub-Milestone | Focus | Status |
4-
|---------------|-------|--------|
5-
| **M2A** | OpenTUI Migration + Core TUI Screens | ✅ Complete |
6-
| **M2B** | Direct Commands | Open (M2A complete) |
7-
| **M2C** | Advanced TUI + Polish + Docs | In Progress |
8-
| **M2D** | Homebrew Distribution | Open (2BD.1 complete) |
3+
| Sub-Milestone | Focus | Status |
4+
|---------------|--------------------------------------|--------|
5+
| **M2A** | OpenTUI Migration + Core TUI Screens | ✅ Complete |
6+
| **M2B** | Direct Commands | Open (M2A complete) |
7+
| **M2C** | Advanced TUI + Polish + Docs | In Progress |
8+
| **M2D** | Homebrew Distribution | Open (2BD.1 complete) |
99

1010
> [!NOTE]
1111
> **Pointer (not a separate tracker):** items remain tracked here in Phase 1.
1212
> The broader TUI aesthetic/UX overhaul (framed panels, app shell, help overlay,
1313
> semantic colours) is *designed and sequenced* in
14-
> [tui-redesign.md](./tui-redesign.md), informed by
15-
> [tui-design-review.md](../technical/tui-design-review.md) — see those docs for
14+
> [tui-redesign.md](../../../tui-redesign.md), informed by
15+
> [tui-design-review.md](../../../../technical/tui-design-review.md) — see those docs for
1616
> the design rationale and branch ordering behind 2TI.12, 2TI.18, 2TM.5/2TM.6.
1717
1818
<details>
@@ -51,12 +51,14 @@ graph TD
5151

5252
> [!IMPORTANT]
5353
> **Dynamic Schema Prerequisite**
54+
>
5455
> - Annual ESFA schema updates must not require code changes.
5556
> - The dynamic schema system (Phases 1-4) enables loading new XSD files at runtime.
5657
> - Phase 5 (TUI schema management) is deferred to Milestone 2.
5758
5859
> [!NOTE]
5960
> **Key**
61+
>
6062
> - CL (base utils)
6163
> - SG (schema system)
6264
> - SS (schema/mapping storage)
@@ -66,27 +68,27 @@ graph TD
6668
- [x] 1CL.2. Create ILR XML generator (minimal valid structure)
6769
- [x] 1CL.3. Build semantic validator (beyond structural checks)
6870
- [x] 1CL.4. Create XML parser module (`src/lib/xml-parser.ts`)
69-
- [x] 1CL.4a. Add XML parser library (fast-xml-parser or equivalent)
71+
- [x] 1CL.4a. Add XML parser library (fast-xml-parser or equivalent)
7072
- [x] 1CL.5. Add unit tests for core transformations
7173
- [x] 1SG.1. Implement **Dynamic Schema (Phase 1): XSD Parser & Schema Registry**
72-
- [x] 1SG.1a. Create schema type definitions (SchemaElement, SchemaConstraints, SchemaRegistry)
73-
- [x] 1SG.1b. Add fast-xml-parser dependency
74-
- [x] 1SG.1c. Implement XSD parser (parse XSD as XML, extract element definitions)
75-
- [x] 1SG.1d. Implement schema registry builder (transform XSD tree into queryable registry)
76-
- [x] 1SG.1e. Add tests against actual schemafile25.xsd
74+
- [x] 1SG.1a. Create schema type definitions (SchemaElement, SchemaConstraints, SchemaRegistry)
75+
- [x] 1SG.1b. Add fast-xml-parser dependency
76+
- [x] 1SG.1c. Implement XSD parser (parse XSD as XML, extract element definitions)
77+
- [x] 1SG.1d. Implement schema registry builder (transform XSD tree into queryable registry)
78+
- [x] 1SG.1e. Add tests against actual schemafile25.xsd
7779
- [x] 1SG.2. Implement **Dynamic Schema (Phase 2): Schema-Driven Validator**
78-
- [x] 1SG.2a. Create schema validator module (validates data against registry constraints)
79-
- [x] 1SG.2b. Implement constraint validation (pattern, length, range, cardinality, enumeration)
80-
- [x] 1SG.2c. Migrate existing validator to use schema registry (remove hardcoded REQUIRED_FIELDS)
80+
- [x] 1SG.2a. Create schema validator module (validates data against registry constraints)
81+
- [x] 1SG.2b. Implement constraint validation (pattern, length, range, cardinality, enumeration)
82+
- [x] 1SG.2c. Migrate existing validator to use schema registry (remove hardcoded REQUIRED_FIELDS)
8183
- [x] 1SG.3. Implement **Dynamic Schema (Phase 3): Schema-Driven Generator**
82-
- [x] 1SG.3a. Create schema generator module (generate XML by traversing registry)
83-
- [x] 1SG.3b. Implement element ordering from xs:sequence
84-
- [x] 1SG.3c. Migrate existing generator to use schema registry (remove hardcoded interfaces)
84+
- [x] 1SG.3a. Create schema generator module (generate XML by traversing registry)
85+
- [x] 1SG.3b. Implement element ordering from xs:sequence
86+
- [x] 1SG.3c. Migrate existing generator to use schema registry (remove hardcoded interfaces)
8587
- [x] 1SG.4. Implement **Dynamic Schema (Phase 4): Column Mapping Configuration**
86-
- [x] 1SG.4a. Create column mapper module (CSV column → XSD path mapping)
87-
- [x] 1SG.4b. Define mapping configuration schema (ColumnMapping, MappingConfig types)
88-
- [x] 1SG.4c. Create default FaC Airtable mapping configuration
89-
- [x] 1SG.4d. Migrate convert workflow to use column mapper (remove hardcoded rowToLearner & rowToDelivery)
88+
- [x] 1SG.4a. Create column mapper module (CSV column → XSD path mapping)
89+
- [x] 1SG.4b. Define mapping configuration schema (ColumnMapping, MappingConfig types)
90+
- [x] 1SG.4c. Create default FaC Airtable mapping configuration
91+
- [x] 1SG.4d. Migrate convert workflow to use column mapper (remove hardcoded rowToLearner & rowToDelivery)
9092
- [x] 1SS.1. Implement storage abstractions for cross-submission history (supports config, mappings, schemas, submissions, history)
9193
- [x] 1SS.2. Configuration system (user preferences + custom field mappings in `~/.iris/config.json`)
9294
- [x] 1SS.3. Load mapping config from file (read JSON, validate structure)
@@ -128,17 +130,17 @@ graph TD
128130
<summary><strong>✅ M2X: OpenTUI Migration (Complete)</strong></summary>
129131

130132
- [x] 1. Foundation ✅
131-
- [x] **2TI.20** — Install `@opentui/core` and `opentui-spinner` (pin exact versions, no `^`/`~`)
132-
- [x] **2TI.21** — Rewrite `app.ts` bootstrap (`createCliRenderer()` replaces terminal-kit fullscreen/grabInput) — **depends on 2TI.20**
133-
- [x] **2TI.22** — Create OpenTUI theme adapter (convert hex theme to `RGBA`; hex strings also accepted directly) — **depends on 2TI.20**
134-
- [x] **2TI.23** — Adapt `router.ts` for OpenTUI screen interface (screen signature changes, renderer context replaces terminal instance) — **depends on 2TI.21**
133+
- [x] **2TI.20** — Install `@opentui/core` and `opentui-spinner` (pin exact versions, no `^`/`~`)
134+
- [x] **2TI.21** — Rewrite `app.ts` bootstrap (`createCliRenderer()` replaces terminal-kit fullscreen/grabInput) — **depends on 2TI.20**
135+
- [x] **2TI.22** — Create OpenTUI theme adapter (convert hex theme to `RGBA`; hex strings also accepted directly) — **depends on 2TI.20**
136+
- [x] **2TI.23** — Adapt `router.ts` for OpenTUI screen interface (screen signature changes, renderer context replaces terminal instance) — **depends on 2TI.21**
135137
- [x] 2. Screen Migration ✅
136-
- [x] **2TI.24** — Migrate Dashboard screen (menu → `SelectRenderable`, layout → flexbox `GroupRenderable`, gradient header retained)
137-
- [x] **2TI.25** — Migrate FilePicker screen (file list → `SelectRenderable` with scrolling, path breadcrumb → `TextRenderable`, manual scroll offset eliminated)
138-
- [x] **2TI.26** — Migrate Processing screen (step display → property-update model with auto re-render, spinner → `opentui-spinner`, no manual redraw loop)
138+
- [x] **2TI.24** — Migrate Dashboard screen (menu → `SelectRenderable`, layout → flexbox `GroupRenderable`, gradient header retained)
139+
- [x] **2TI.25** — Migrate FilePicker screen (file list → `SelectRenderable` with scrolling, path breadcrumb → `TextRenderable`, manual scroll offset eliminated)
140+
- [x] **2TI.26** — Migrate Processing screen (step display → property-update model with auto re-render, spinner → `opentui-spinner`, no manual redraw loop)
139141
- [x] 3. Cleanup ✅
140-
- [x] **2TI.27** — Update documentation that still references terminal-kit; unify `app.test.ts` to use shared mock fixture — **depends on 2TI.24, 2TI.25, 2TI.26**
141-
- [x] **2TI.28** — (merged into 2TI.27) Update TUI test fixtures for OpenTUI mock renderer interface; verify on target terminal environments
142+
- [x] **2TI.27** — Update documentation that still references terminal-kit; unify `app.test.ts` to use shared mock fixture — **depends on 2TI.24, 2TI.25, 2TI.26**
143+
- [x] **2TI.28** — (merged into 2TI.27) Update TUI test fixtures for OpenTUI mock renderer interface; verify on target terminal environments
142144

143145
</details>
144146

@@ -166,10 +168,10 @@ All tasks complete — no open tasks in M2A.
166168
- [x] **1WA.22** — Block convert from producing XML when validation fails (currently saves output even for completely invalid input like `hey, hey, hey`; should abort before `generate` step if error count > 0, or at minimum require user confirmation)
167169
- [x] **1WA.23** — Fix validate workflow routing — currently routes to failure screen on first missing field instead of collecting all validation issues and showing the explorer. The validator itself collects all issues; the workflow layer treats the first error as fatal.
168170
- [x] **2TI.30** — Fix validation explorer UX issues:
169-
- Status bar says `[Tab] Switch filter` but `TabSelectRenderable` uses `[←→]` arrows
170-
- Tab switching causes display glitches (same bordered-container rendering issue as check-results)
171-
- Row numbers 0-indexed — should display as 1-indexed for non-dev users
172-
- Single-issue display doesn't indicate it's the first occurrence of a repeated error
171+
- Status bar says `[Tab] Switch filter` but `TabSelectRenderable` uses `[←→]` arrows
172+
- Tab switching causes display glitches (same bordered-container rendering issue as check-results)
173+
- Row numbers 0-indexed — should display as 1-indexed for non-dev users
174+
- Single-issue display doesn't indicate it's the first occurrence of a repeated error
173175
- [x] **2TI.32** — Two-file-picker for cross-check workflow — user must select both current and previous submission files (not auto-select from history array). Blocks 2TI.15 completion.
174176
- [x] **2TI.17** — Test TUI with real CSV exports from Airtable — **depends on 2TI.29, 1WA.20, 1WA.21, 1WA.22, 1WA.23, 2TI.30, 2TI.15**
175177

@@ -284,6 +286,8 @@ graph TD
284286
285287
2TI.12["`*2TI.12*<br/>**SHOULD**<br/>contextual help`"]:::should-blocked
286288
2TI.31["`*2TI.31*<br/>**SHOULD**<br/>success proof`"]:::should-blocked
289+
2TM.7["`*2TM.7*<br/>**SHOULD**<br/>fix mapping-config typo`"]:::should-open
290+
2TI.34["`*2TI.34*<br/>**SHOULD**<br/>fix crosscheck filePath`"]:::should-open
287291
2TS.2["`*2TS.2*<br/>**COULD**<br/>schema manager screen`"]:::could-blocked
288292
2TS.3["`*2TS.3*<br/>**COULD**<br/>schema version selector`"]:::could-blocked --> 2TS.4
289293
2TS.4["`*2TS.4*<br/>**COULD**<br/>dynamic migration guidance`"]:::could-blocked
@@ -308,7 +312,7 @@ phase1{"`**M2C**<br/>Complete`"}:::mile
308312
2UD.1 -.->|optional| 2UD.2 & phase1
309313
2TS.2 -.->|optional| 2TS.3 & 2TI.19 & 2TC.2
310314
2TC.2 -.->|optional| 2TC.3 & 2TC.4
311-
2TI.33 & 2TM.5 & 2TM.6 & 2TI.19 & 2TS.4 & 2UD.2 & 2DC.4 & 2TC.1 & 2TC.2 & 2TC.3 & 2TC.4 -.->|optional| phase1
315+
2TI.33 & 2TM.5 & 2TM.6 & 2TI.19 & 2TS.4 & 2UD.2 & 2DC.4 & 2TC.1 & 2TC.2 & 2TC.3 & 2TC.4 & 2TM.7 & 2TI.34 -.->|optional| phase1
312316
313317
classDef must-open fill:#D6A3BF,color:#000;
314318
classDef must-blocked fill:#F3D8E6,color:#000;
@@ -338,6 +342,8 @@ classDef mile fill:#E8EFF6,color:#000;
338342
- [ ] **2TI.18** — Add visual feedback (spinners via `opentui-spinner` with 80+ animations and dynamic color effects; transitions via OpenTUI Timeline API) — **depends on 2DC.3**
339343
- [ ] **2TI.31** — Show validation proof on success screen (summary of checks passed, schema version validated against, learner count breakdown — gives user confidence the output is genuinely valid) — **depends on 2TI.10**
340344
- [ ] **2TC.1** — Clean test history after test runs (prevent test submissions from polluting global history; use isolated history per test or cleanup in afterEach) — **depends on 2TI.18**
345+
- [ ] **2TM.7** — Fix `IlrIlrMappingConfig` typo in mapping-save & storage/create (doubled `Ilr` prefix in `import type` at `src/tui/screens/mapping-save.ts:18` and `src/lib/storage/create.ts:18` imports a non-existent type; the real `IlrMappingConfig` is used in three type positions but silently resolves to `any`. Bun erases it at runtime so no crash, but the mapping config loses all type safety. Fix the import name; `tsc` clears.)
346+
- [ ] **2TI.34** — Fix missing `filePath` on `previousSubmission` in cross-check workflow (the object literal at `src/lib/workflows/crossCheck.ts:144` is typed `HistoryEntry` but omits the required `filePath` field. Latent today since that branch never reads it, but it violates the type contract — any future read of `previousSubmission.filePath` yields `undefined`. Add `filePath: input.previousFilePath`.)
341347

342348
### Could Have
343349

@@ -387,6 +393,8 @@ graph TD
387393
2TC.2["`*2TC.2*<br/>util<br/>history cleanup`"]:::could-blocked
388394
2TC.3["`*2TC.3*<br/>enhance<br/>dual-picker`"]:::could-blocked
389395
2TC.4["`*2TC.4*<br/>enhance<br/>bordered panel`"]:::could-blocked
396+
2TM.7["`*2TM.7*<br/>fix<br/>mapping-config typo`"]:::should-open
397+
2TI.34["`*2TI.34*<br/>fix<br/>crosscheck filePath`"]:::should-open
390398
391399
%% Build & Distribution %%
392400
2BD.2["`*2BD.2*<br/>build<br/>GH Actions release`"]:::could-open
@@ -414,7 +422,7 @@ phase1{"`**Phase 1**<br/>Complete`"}:::mile
414422
2UD.1 -.->|optional| 2UD.2 & phase1
415423
2TS.2 -.->|optional| 2TS.3 & 2TI.19 & 2TC.2
416424
2TC.2 -.->|optional| 2TC.3 & 2TC.4
417-
2TI.33 & 2TM.5 & 2TM.6 & 2DC.4 & 2TI.19 & 2TS.4 & 2UD.2 & 2TC.1 & 2TC.2 & 2TC.3 & 2TC.4 -.->|optional| phase1
425+
2TI.33 & 2TM.5 & 2TM.6 & 2DC.4 & 2TI.19 & 2TS.4 & 2UD.2 & 2TC.1 & 2TC.2 & 2TC.3 & 2TC.4 & 2TM.7 & 2TI.34 -.->|optional| phase1
418426
419427
classDef must-open fill:#D6A3BF,color:#000;
420428
classDef must-blocked fill:#F3D8E6,color:#000;

docs/roadmaps/2026-q1/phase-2-production-features.md renamed to docs/roadmaps/archive/2026/01/phase-2-production-features.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Phase 2: Production Features
22

3-
| Milestone | Focus | Status |
4-
|-----------|-------|--------|
5-
| **M3** | CLI Completion | Blocked (depends on Phase 1) |
6-
| **M4** | Desktop Interface | Blocked (depends on M3) |
7-
| **M5** | Production Docs | Blocked (depends on M4) |
3+
| Milestone | Focus | Status |
4+
|-----------|-------------------|--------|
5+
| **M3** | CLI Completion | Blocked (depends on Phase 1) |
6+
| **M4** | Desktop Interface | Blocked (depends on M3) |
7+
| **M5** | Production Docs | Blocked (depends on M4) |
88

99
**Prerequisite:** [Phase 1: MVP Features](./phase-1-mvp-features.md) — All M2A, M2B, M2C tasks complete
1010

@@ -72,6 +72,7 @@ classDef mile fill:#9ff;
7272
7373
> [!NOTE]
7474
> **Categories:**
75+
>
7576
> - GC (GUI Components)
7677
> - NB (Native Builds)
7778

0 commit comments

Comments
 (0)