The system one student runs a degree on: how Module and Research-project folders are laid out and
named, how the work in them is tracked, and what the semester's calendar and the personal site are
fed from. It is
public because the system is worth copying and costs nothing to share — but it holds only the
system. The coursework it organises lives elsewhere and never enters this repository
(docs/adr/0002).
A Jerome-Group repository. See MAP.md to find your
way around and AGENTS.md for how work is done here.
✅ V1 proved. The CLI previews and explicitly publishes additive seeds, audits the configured
monitoring cohort, and records append-only private observations. Modules retain semester/module-code
identity; Research projects use a separate configured root, stable key and programme profile.
Past and future Modules and inactive Research projects remain explicit targets; historical Module
differences are assessed in read-only migration mode. The operator guide and
acceptance evidence cover operation and boundaries. Y1S1 and Y1S2 remain
historical inputs awaiting separately approved repair;
ntulearn already writes current module material into
contract-declared importer roots.
The separately gated repair command now executes only an approved, Drive-ID-bound historical
migration plan after fresh inventory and dual recovery verify. It previews by default and has no
permanent-delete or Trash operation.
Calendar setup now binds the Google primary calendar as Academic, reuses Commitments and Routine, and previews any missing secondary-calendar creation. The ordinary Proposal/Promotion path also previews and migrates reviewed recurring Routine series. Exact IDs remain in private configured state.
docs/module-folder-contract.md — the folder and naming
contract every module folder follows: the universal structure, the parts that appear only when the
module has them, the naming rules, and where LaTeX builds go. It is the interface the
ntulearn importer writes into.
docs/research-project-folder-contract.md — the
separate contract for human-first Research projects: controls, sources, supervisor meetings,
Owner-authored Research, profile-derived Deliverables and their Tasks/Calendar boundaries. It
seeds no NTULearn surface.
Copy academic-os.config.example.json to the gitignored academic-os.config.json, replace its
placeholder roots, declare each semester's status, relative root and module codes, and optionally
declare Research projects under a separate root. Exactly one semester is active; each Research
project declares its own status. Then:
npm ci
npm run build
node dist/src/cli.js audit --config academic-os.config.jsonAdd --json for the versioned machine-readable report. Audit never changes its target. Each
successful target atomically appends a complete observation beneath the configured private
stateRoot, then reports new, unchanged, resolved, incompatible, or contract-version-changed
history explicitly. Module and Research-project observations use separate target schemas and
history namespaces. Keep that root outside the Drive mount and this repository; configuration
rejects either unsafe location.
Name both fields to audit one configured module outside routine monitoring:
node dist/src/cli.js audit --config academic-os.config.json \
--semester Y2S2 --module MH2200Add --migration only for a configured past-semester target. It evaluates that historical module
with historical-migration interpretation. An explicitly requested past module may also be audited
normally as read-only acceptance evidence; neither mode changes it or adds it to the active cohort.
For one explicit module, add its folder ID under driveApi.moduleFolderIds and pass
--inventory drive-api. This optional route uses Application Default Credentials with only
drive.metadata.readonly; it enriches the same audit with provider IDs and available metadata.
Without that flag, credentials and the Drive API are never consulted. Keep credentials, raw API
responses, observations, and reports outside tracked content.
Audit one Research project by its stable configuration key:
node dist/src/cli.js audit --config academic-os.config.json \
--research-project example-projectSet seedTarget in the same local configuration, prepare an approved Module Profile and Module
Definition, then preview every proposed creation:
node dist/src/cli.js seed --config academic-os.config.json \
--profile /path/to/approved-profile.md \
--definition /path/to/approved-definition.yamlAdd --apply only after reviewing the preview. For a new module, the command builds and audits a
unique staging tree, then atomically renames the complete tree to its published directory name. For an
existing partial module it publishes only missing operations. Every apply is recorded in an
append-only journal beneath the private stateRoot; existing matching operations are skipped and
content is never overwritten, moved, renamed, or removed.
After an interrupted apply, rerun the same command first without --resume. It recomputes target
preconditions and reports completed and remaining operations without changing Drive. If the report
is safely-resumable, rerun with both --apply --resume. Changed controls, contract version,
target identity, conflicts, or ambiguous journal state block continuation with evidence. Staging
artifacts are removed after completion or a safely handled failure; the private journal remains.
Declare research.root and the project key in private configuration, then supply its approved
Project Profile and closed Project Definition:
node dist/src/cli.js seed --config academic-os.config.json \
--research-project example-project \
--profile /path/to/approved-project-profile.md \
--definition /path/to/approved-project-definition.yamlPreview first; add --apply only after review. The same staged publication, journal/resume,
containment and post-write verification boundary applies. The generic Research seed contains no
NTULearn root; its programme profile derives only the contract's named additions.
Configure the Calendar block in the same gitignored local configuration, including a current Management horizon and distinct scheduled-read and interactive-write credential files. Preview setup first:
node dist/src/cli.js calendar setup --config academic-os.config.jsonThe primary calendar is bound as Academic and is never created or renamed. Existing Commitments
and Routine calendars are reused. Add --apply only when the report previews missing secondary
calendars; rerunning setup reuses the resulting exact IDs. Add --json for the versioned report.
Install the daily private macOS Refresh from the operator guide.
The contract is the first piece rather than the whole of it. The repository is meant to run the academic side end to end, and the pieces it is shaped for are:
| Piece | What it is |
|---|---|
| Module folder contract | The layout and naming every module folder follows — here now |
| Research-project folder contract | A reusable pure-mathematics-oriented research core with programme profiles — here now |
| Teaching workspace | The 70 Learning half of the contract: teaching a subject as a way of learning it |
| Tasks | Module and Research-project work in Google Tasks, mirrored into each target's Task register; repository changes remain Issues |
| Calendar | Classes, assessments, meetings, appointments and recurring life events in Google Calendar; tasks and self-directed work stay elsewhere |
| Site data | What homepage reads to publish the parts of this that are meant to be seen |
Undergraduate now, and shaped so postgraduate work lands in the same place rather than in a second repository.
Please do. It is MIT licensed — take the contract, rename the folders, keep the parts that work for your degree and drop the rest. No attribution required and none expected.
The licence covers what is in this repository and nothing else. The coursework a module folder
holds is not here and is not the Owner's to grant — see
docs/adr/0003 for where that line falls.