Team DSTIEngineering and school systems
On this page
OverviewWhen the requirement changedFour languagesConsistencyNaming the editSame-thing identitymanager2Review means shipWhat is kept
DSTI TechBlog / Team DSTI
Team DSTIGovernance · identity · delivery

The promises behind the pages: engineering dsti.school, part 2

A long read about how the system behind a static website became an industrialised publishing practice: how languages, links, identities, editing and release became organisational promises that the estate can remember, test and keep.

information-systemscontent-governancelocalisationlinked-dataci-cdstatic-site

DSTI TechBlog · Team DSTI

A note on version, and on honesty. This article describes dsti.school as it stood at the version V377 immediately before V378, where this article has been published. The estate frozen in the public snapshot whose figures appear in the panel above is indeed V377. Preparing this page for publication was not neutral: running it through the estate's own rules uncovered assumptions that had to be rebuilt before it could ship — fitting, for a piece about making a system keep its promises. Concretely:

  • Locale model — the build could not represent a page that existed in English before its translations. It was generalised so that French, Mexican Spanish and Brazilian Portuguese now follow one authored-only rule, removing a split that treated French and Spanish differently from Portuguese and two hardcoded path exceptions. This is the first page created English-first that way, instead of "all locales at once". And it's safer.
  • Coherence gate & card-count check — the blog's own integrity check asserted a frozen catalogue by fixed counts, those are now derived from the estate.

The changes are behaviour-preserving — verified page-for-page against the previous build — and locked by seven new regression tests and two updated governance documents.

Part 1 told the story of rebuilding dsti.school: the fieldwork that preceded the code, the choice of a static website, and the gates that made a release verifiable. This second part begins where that account ended.

Once the new site existed, the difficult question moved beyond building a page: how could the organisation keep a promise?

A fee shown in four languages should remain the same fee. A professor linked from an article should remain the same person as the professor on the Faculty page. A colleague changing an admissions date should be able to concentrate on the date while the release machinery does its work beneath it. What a publisher approves should be exactly what reaches the public estate. And a future engineer should be able to discover why those rules exist from the package itself, with the reasoning preserved beyond old messages and half-remembered incidents.

Those are organisational promises before they are technical requirements. The engineering came afterwards.

Figure — the ADIS chain
ADIS · THE DISCIPLINE Analysis before design; design before code. Organisationnames the need the command Analysisthe WHAT + boundary describe the what, resist the how Designthe HOW · blueprint turn what into how Engineeringbuild + verify code follows design Code is a consequence of design, not its driver — the order never reverses. The organisation commands; engineering answers: need → what → how → built-and-proven.
The ADIS chain: organisation names the need, analysis fixes the what and the boundary, design turns it into the how, engineering builds and verifies.

This is the order taught in Analysis & Design of Information Systems (ADIS) at DSTI School of Engineering. The organisation states the need. Analysis establishes what must hold and where its boundary lies. Design decides how the system will hold it. Engineering builds and verifies the result. The larger discipline is simple to state: code is a consequence of design, and design is a consequence of the organisation's command.

That sequence is easy to recite and surprisingly difficult to keep. Technical work creates its own momentum. Once a team can build something, it becomes tempting to let the available technology define the problem. A database schema becomes the organisation's model because it already exists. A deployment system acquires ceremonies because its first implementation happened to need them. A translation tool begins deciding academic vocabulary because it can produce plausible sentences quickly.

ADIS asks us to travel in the other direction. What must remain true? Who has authority to decide it? Which boundary does the requirement cross? What evidence would let us refuse an incorrect result? Only after those questions are settled do we choose a representation or a tool.

The website now follows that order. Its engineering can be read through three recurring ideas:

The promise is the unit of engineering.

01When the requirement changed

The first requirement was modest: DSTI School of Engineering needed a modernised website.

The earliest working method matched it. Pages were built through conversations with ChatGPT and exchanged as ZIP archives. For a brochure assembled by one person, that was quick and adequate. The archive contained the visible result; the conversation contained most of the reasoning; the person who had conducted the work connected the two.

The organisation then began asking the website to guarantee the relationships behind what it displayed. That larger requirement called for a different method.

Could the same admissions information remain coherent across languages? Could a change be handed to another colleague with its context already preserved? Could a release be rejected because a hidden machine-readable statement had drifted even though the page still looked correct? Could we prove that the bytes approved on staging were the bytes later published? Could an editor work safely while deployment remained the responsibility of the release system?

The distinction is important. A folder of files can contain a correct answer. An operational authority must also explain why the answer is correct, who is entitled to change it, and which future change would invalidate it. A chat transcript preserves a discussion; the package needs its decisions in a form that people and machines can query, test and interpret consistently.

The project's memory therefore moved into one governed repository using Git, a distributed version-control system. Version control records changes to a body of files and the order in which they were accepted. Its value here comes from giving the organisation a common history and a precise point from which every build can begin; truth still depends on the authorities and gates applied to that history.

In this package, Git became the authoritative package memory — one of its components being the Engineering Principles. That means more than saving source code. It includes the rules, schemas, translation authorities, tool descriptions, tests and operating documents needed to understand and reproduce the system. The repository is a shared starting point for people, agents and pipelines.

This is close to the idea of a single source of truth, with an important qualification. The repository governs the package and the candidate we intend to build. The current live estate exists in its own right, and a rollback snapshot records the previous public state. Source, operational package and live predecessor each have a distinct purpose; keeping those purposes separate removed one source of earlier over-engineering.

The mature model is deliberately less dramatic:

  1. the package and its operating rules are governed in Git;
  2. the maintained content and the publication projection are governed in Git;
  3. the previous live estate is retained independently as one operational rollback boundary.

That separation keeps history useful while allowing each action to follow its actual authority. A content correction can become a same-version patch. A new public version can advance both identity and publication date. A deployment captures the current live estate before replacing it; the rollback boundary therefore reflects what was genuinely public at that moment.

The larger lesson extends beyond “use Git”: a guarantee needs somewhere durable to live. Each new organisational promise acquired a declared boundary, an authority that could remember it, and a gate that could refuse to break it. The rest of the architecture follows from that choice.

02The same school, in four languages

DSTI School of Engineering is a French school whose students and families come from far beyond France. Every reader should be able to meet the school in a language intended for them.

The estate therefore has four governed locales. A locale is more specific than a language name: it combines language with the regional conventions that influence vocabulary, punctuation and expected usage. The four variants are British English as the source, standard France French, Mexican Spanish and Brazilian Portuguese. Mexican Spanish serves a Latin American audience through one coherent regional standard; Brazilian Portuguese gives Portuguese-speaking readers their own natural edition. These explicit standards give human editors and translation systems more precise instructions than the broad labels “French”, “Spanish” and “Portuguese”.

This work is localisation: it preserves both meaning and the way a reader expects that meaning to be expressed. A faithful sentence can still feel translated, while a natural sentence can quietly change a fact. Both dimensions matter.

Figure — one source, four locales
LANGUAGES · §2 One source, four first-class locales. British Englishen-GB · the source Français (FR)fr · standard France French Español (MX)es-MX · Latin America Português (BR)pt-BR · Brazil reciprocal hreflang (+ x-default) · slugs are never machine-translated Programme substance — course names, modules, study-mode labels — stays canonical English in every locale. en-GB is authored; each target follows governed guidance, two passes and human review — never a bolt-on translation.
One source, four first-class locales: en-GB source, fr, es-MX and pt-BR, linked by reciprocal hreflang; programme substance stays canonical English.

From one generator file to an authority system

In June, translation governance was one text file: translations_principles_generator.txt. Its full title called it the “DSTI translation & localisation principles — generator”, and its opening instruction was literally a context message that could be pasted into a new chat. It was useful. It told the next language model that British English was the source, defined French and Mexican Spanish, required a faithful pass followed by a naturalness pass, protected markup and official names, and recorded recurring vocabulary.

It also belonged to the way the project worked at that time. The file explained which ZIP archive to open first, where companion summaries should sit, and which temporary columns an Excel workbook should use to assess and return translations. Enduring language rules and temporary operating procedure occupied the same document. Brazilian Portuguese would later join as an equal target locale.

That generator transferred context effectively between chats. A complete organisational authority demanded more: a future operator had to distinguish current language rules, a retired workbook procedure and evidence from one translation exercise across 481 lines. The next design therefore added a validated shape and equal governance for every locale.

The current system separates those responsibilities while preserving the original file in Git history. The active operational hierarchy is explicit:

  1. LANGUAGE_AUTHORITY.md and LANGUAGE_AUTHORITY.json declare British English as the normal source, name the three target locales and state which authority wins when files disagree.
  2. locale-profiles.json gives France French, Mexican Spanish and Brazilian Portuguese the same machine-readable fields: document-language code, Open Graph locale, route authority, authoring interface and mandatory human review.
  3. The common LOCALE_LANGUAGE_GUIDANCE.schema.json schema defines what every locale guidance file must contain.
  4. FR_LANGUAGE_GUIDANCE.json, ESMX_LANGUAGE_GUIDANCE.json and PTBR_LANGUAGE_GUIDANCE.json carry the actual language decisions for each locale.
  5. The page-locale map records which maintained source page belongs with which translated page and which route each one owns.
  6. Stable data-dsti-element-id and data-dsti-source-id values connect a translated element to the English element it translates.

The locale guidance files are deliberately structured authorities. Their fields separate register, formatting, preservation, sources and terminology. A terminology entry can record the English concept, accepted contextual choices, discouraged forms and the reason for the decision. Everything in the file is current guidance, and every locale follows one uniform model.

That matters in practice. “Digital jobs”, for example, is understandable when translated literally, but the literal result can imply work performed online. The intended meaning concerns careers in the technology sector. The Mexican-Spanish authority therefore records empleos en el sector tecnológico and contextual alternatives. The Brazilian-Portuguese authority prefers profissões na área de tecnologia, empregos na área de tecnologia or carreiras em tecnologia, depending on whether the sentence concerns professions, vacancies or career paths. The translation session's discovery now lives as a reusable decision in the authority.

Scientific terminology is resolved concept-first. The translator starts from the English concept, uses Wikipedia's interlanguage relationship to discover the established target-language term, checks professional usage, and records the contextual choice. Official names retain priority: a DSTI programme, course, named teaching unit, product, technology or machine token remains protected.

The first design boundary therefore remains clear. The human account of DSTI travels: the admissions path, the experience of international students, the school's environment and the explanations around a programme. The academic substance retains its canonical English identity: official programme names, course names, course descriptions and named teaching units remain consistent in every locale.

This can look unusual at first. A Portuguese page may contain a course title in English inside otherwise natural Brazilian Portuguese. That is deliberate. The title identifies one academic object used across timetables, records and programme authorities. Translating it would create a second label whose relationship to the official course would have to be maintained indefinitely. The surrounding explanation belongs to the reader's language; the academic identity belongs to the programme authority.

What translating one page now involves

The process begins with a maintained source/target pair governed as one editorial unit.

  1. Fix the source and scope. Work begins from one clean Git commit. The page-locale authority identifies the British-English source and the French, Spanish or Portuguese target.
  2. Load the target-locale authority. The translator reads the common policy and the target's JavaScript Object Notation (JSON) guidance: register, address to the reader, number and currency presentation, protected forms, recurring terminology and contextual alternatives.
  3. Translate for fidelity. The first pass preserves every fact, qualification and emphasis while resisting explanatory additions or editorial interpretation. Official programmes, courses and technologies remain unchanged.
  4. Rewrite for naturalness. The second pass removes calques, false friends, source-language word order and register drift. Mexican Spanish uses and avoids Spain-only vocabulary; Brazilian Portuguese uses natural Brazilian constructions; France French remains modern, neutral and free of regional affectation.
  5. Protect the structure through Dsti.ContentInventory. Human-readable text may sit inside <span>, <strong> or links, and the inventory exposes it to the editor as identified content, separate from the surrounding HyperText Markup Language (HTML). Dsti.ContentInventory maps the value to its stable data-dsti-element-id and, for a translation, to the source lineage carried by data-dsti-source-id. The editor changes the identified value while tags, attributes, identifiers and governed routes remain intact. The inventory's role is identification; the language authority and two human passes govern the translation itself. Structural and semantic changes are made explicitly in maintained HTML, while generated Markdown and distribution files serve as review surfaces.
  6. Review what the build produces. The generated page Markdown twin makes a prose review fast. HTML is then inspected where metadata, links, nested markup or JavaScript Object Notation for Linked Data (JSON-LD) matter. A human remains responsible for meaning and naturalness.
  7. Prepare the estate. The governed build regenerates everything and runs the translation estate gate over the complete built candidate—the exact form eligible for publication.

The page is handled as a source-bound object throughout. If the Portuguese translation of one paragraph fails, the report identifies the Portuguese data-dsti-element-id, the English data-dsti-source-id, and both values. The editor can return directly to the exact maintained element that needs correction, avoiding a search through line 417 of minified output.

What the translation gate actually proves

The whole-estate gate enumerates every governed full-page group across the website and the collateral subdomains, then evaluates each materialised source/target pair. On a recent candidate, that meant 211 pairs in 73 groups. It is run inside prepare, because only the built candidate contains the complete form that would ship.

The gate checks a deliberately narrow set of deterministic invariants:

If one of those checks fails, the candidate is cleared and therefore remains ineligible for publication. A Markdown worklist and a machine-readable JSON report remain outside the candidate. The operator fixes maintained source and runs prepare again; the new preparation replaces the previous attempt and presents one current candidate.

The gate scores deterministic coherence. Human reviewers judge whether a sentence is idiomatic, whether feels welcoming in its particular paragraph, and whether a translated explanation carries the source's emphasis. Number and currency presentation also remains contextual: local formats, written numerals, dates and ranges produced too many false positives for a locale-neutral mechanical rule. Critical numbers that belong to a governed domain—an admissions date, a fee or a curriculum total—are protected by that domain's authority and gate; the linguistic review remains responsible for their expression in prose.

That division is more useful than an all-purpose “translation score”. The machine protects what can be stated exactly. The language authority guides what depends on context. A human decides whether the result is both faithful and worth reading.

The four pages also have to identify one another to machines. Each has its own Uniform Resource Locator (URL), a canonical address that declares the preferred public URL, and reciprocal alternate-language references. Search engines commonly know those alternate relationships through hreflang. The page title must agree with its social-sharing title expressed through the Open Graph protocol. Its structured data must give the Portuguese page its Portuguese identity and route.

These are operational declarations as well as editorial ones. A reader can see correct Portuguese while a crawler is told that the page is English, or while the language selector points back to an English resource. Language coherence therefore has to include visible text, links and machine-readable metadata together.

Adding a locale extends every relationship in which its page participates: title, alternate link, structured-data block, redirect and cross-reference. Every target locale therefore enters the same schema, page-pair workflow and two-pass review. The whole estate is checked in every available locale; the evidence may then show that a defect is locale-specific. Language becomes a dimension of the diagnosis while the defect itself remains evidence-led.

The authority is now the locale family, the language files, the route map and the source lineage acting together. The boundary remains the line between localisable explanation and canonical academic substance. The deterministic gate protects what machines can know; the two human passes protect what only readers can judge.

Language shows the method at one boundary. The same method becomes more demanding when the relationships span the complete estate.

03Consistency is an estate property

The public system is larger than the main website. It includes four collateral families—facts, information, Sophia and awareness—each with its own routes and language variants. Taken together, the governed publication contains 742 deployable files across 284 HTML pages, 285 JSON-LD blocks and 363 managed redirects.

HTML describes the structure of a web page. JSON-LD expresses entities and relationships in a machine-readable graph while remaining embeddable in that page. The two views can disagree even when the browser renders something attractive. The visible programme may name one professor while the JSON-LD names another. A translated route may display French and still advertise an English canonical address. Those website defects can remain visually plausible.

The estate totals describe its scale. Consistency comes from a future build stopping when one of the recorded relationships breaks.

Figure — the consistency surface
CONSISTENCY SURFACE · §3 A language is a dimension multiplied through everything. en-GBfres-MXpt-BR main-website facts info Sophia awareness shipped not in this locale WHOLE-ESTATE TOTALS 742deployable files 284 · 285pages · JSON-LD blocks 363governed redirects 211 / 73translation pairs / groups 11named build gates each fails the build, not a report. Every cell is a promise; a broken promise fails the build. "One more language" is never one more page.
The consistency surface: website and collateral families crossed with four locales, governed by estate-wide gates.

A page checker and an estate checker answer different questions. The page checker reads one document, evaluates its links, metadata and semantic statements, then moves to the next. Its deliberately bounded method is predictable: take a page, inspect the internal DSTI references it contains, verify their target and language, record the result, continue. It consumes the supplied estate authority and stays within the current page; recursive graph construction belongs outside this operation.

At the governed source layer, the inventory records 2,563 visible internal references and 4,140 internal references in total when canonical declarations, hreflang, Open Graph and JSON-LD are included. Those figures describe the relationships the system must preserve; the built-estate occurrence count in the hero describes every place those relationships are materialised.

The estate-level view then asks whether those independent page results agree with one another. Internal links must resolve to the intended target and locale. Relative links are used within one host, while links between the website and a collateral use full addresses because the host boundary is meaningful. Media references must use the governed media host, except for deliberately inlined data. Canonical and alternate routes must agree. A translated page's structured data must identify that translated page in its own locale. Course-card content must remain canonical English. Page titles and their Open Graph and social twins must remain one title. Sitemaps and llms.txt—the concise estate index intended for large language models (LLMs)—must carry the sealed publication date, and collateral language files must reference all their governed siblings.

The checker combines the locale authority with independent discovery of the pages that actually exist. If a maintained page is absent from the authority, discovery makes the discrepancy visible so the authority can be updated. This pairing proves the coherence of the complete discovered estate as well as the registered set.

The distinction between local and global rules matters. “This link resolves” is page-local. “This link resolves to the correct language wherever that target has a localised edition” requires knowledge of the estate authority. “This media source uses the correct host” is local. “Every public media identity is represented consistently in page metadata and structured data” crosses documents. A good gate states which sort of claim it makes.

The programme-hours gate provides a numerical example of the same principle. The MSc in Data Analytics with AI displayed 835 hours as its headline volume while its own component structure totalled 725 hours. All four locales repeated 835, so a cross-locale comparison alone saw perfect agreement. The pages were consistently wrong; the visible total is now corrected to 725 hours in every locale.

The resulting programme-hours gate is therefore both intra-page and cross-locale. It derives its scope from stable content lineage and the shapes found in the pages, and it recognises that programmes express volume in different ways. The MSc and Executive pages compare a headline with their declared taught total; the Bachelor of Science (BSc) checks each year's teaching + support = total statement while keeping its European Credit Transfer and Accumulation System (ECTS) headline outside an hours rule. This is what a domain invariant adds: an explicit statement of which numbers must agree and why.

The package's preparation stage groups these concerns into explicit gates, each capable of reporting the relationship it protects. Among them are:

CSS governs presentation: type, spacing, responsive layout and the behaviour that turns the same HTML into a laptop or phone interface. Its optimisation is accepted when the package proves that the optimised projection remains equivalent to the governed source within the defined contract; completion of a minifier—a tool that removes unnecessary characters to reduce file size—is only the transformation step.

These gates answer a different question from the document validators described in Part 1. HTML conformance establishes that one document is syntactically valid. The newer gates operate over the estate as a set of related documents, establishing that a Portuguese collateral links to the Portuguese guide and that the same admissions date appears everywhere it should.

The checker classifies each failure according to the authority needed to resolve it. Some reveal missing content. Others reveal an incomplete authority. A course may have a historical code collision whose resolution requires an academic decision; a mechanical edit would be insufficient. Precise reporting puts each case before the right authority.

That is why the system can be coherent and still need readers. The gates prove links, identities, dates and declared language relationships. Human readers assess tone, emphasis and pedagogic quality. Mechanical consistency provides the floor on which editorial quality can stand.

04An edit should name what it changes

Once several people and agents can edit the estate, a durable content model must identify the intended value directly. “Open the file and find the text” binds an editor to markup, encourages accidental changes around the intended one, and makes concurrent work difficult to reason about.

Traditional web publishing often hides this complexity behind a Content Management System (CMS). A CMS such as WordPress shields an editor from raw HTML through fields, previews and publishing controls. DSTI kept its static architecture and met the same human need through a comprehensible surface for changing dates, labels and records while the internal page structure remains protected.

The result is an identified content surface. Every editable element has a stable governed identity, and an edit names that identity directly. The English source element carries its own identity; translated elements point back to that source identity through their lineage. A French paragraph can move within a page while remaining the same editorial object.

Admissions dates, partner records, media, redirects and student stories each have a governed operation with their own inputs and preconditions. Larger changes are arranged as work packages in dependency order before editing begins. The machine-readable form is a directed acyclic graph (DAG): a set of tasks connected by one-way dependencies. Its acyclic structure gives every construction step a resolvable predecessor, while the graph shows what can proceed in parallel and which authority must be settled first.

Figure — ContentInventory as the spine
DSTI.CONTENTINVENTORY · §4 The workbook that became the spine. Excel-shapedworkbook Dsti.ContentInventoryid-anchored inventory governedprimitives gatesfail closed Primitives: admissions · partner-directory · media · redirects · student-videos · translation. Every editable text node maps to a stable id; structural, linking and semantic changes remain explicit source work. The familiar workbook became a stable content-addressing spine without becoming a second source of truth.
ContentInventory: a workbook-shaped editing surface became an id-anchored inventory feeding governed content operations.

Dsti.ContentInventory is the spine of that arrangement. It began as a Microsoft Excel-shaped replacement for quick WordPress editing and became the map between human-readable content and stable page elements. The spreadsheet remains useful precisely because it is familiar. The engineering lies in what now surrounds it.

An edit session is tied to a clean Git state, a schema—a machine-readable definition of the permitted structure—an editor and an explicit scope. Exclusive scope prevents two sessions from quietly claiming the same content. Generated Markdown twins provide a plain-text reading surface, while maintained HTML remains the source for structural and semantic changes. Preparation keeps the workbook coupled to the pages by checking that the generated workbook remains substantively equivalent to the governed canonical one.

This distinction prevents a familiar failure. If a generated file is hand-edited, the change may look correct until the next build regenerates it from source and erases the work. A governed operation changes maintained source, then lets the build produce the distribution, the page Markdown twins and the inventory evidence. Build output serves as the inspection surface; maintained source remains the editing surface.

The tool itself had to mature with the content model. Part 1 described a committed .NET 8 binary. .NET is Microsoft's cross-platform software framework; the current ContentInventory tool is built from governed source with the .NET 10 software development kit (SDK), so the repository carries source in place of a compiled binary. Rebuilding from source was coupled with fixing a Brazilian-Portuguese identification defect: newly identified elements had been minted with pt.br. while the governed lineage is pt.. The current source build consistently produces the governed pt. form.

This is a useful example because governance also extends to the tools behind the visible website. A tool that identifies content can create drift just as surely as an editor can. Once that was understood, the tool entered the same authority-and-gate model as the pages it serves.

The editing discipline includes direct HTML work for genuinely structural changes: adding a relationship in JSON-LD, splitting main professors from support professors on a course card, or introducing an accessible control. Those changes belong in maintained source and require an engineer. The identified surface makes the boundary explicit and reserves spreadsheet-shaped editing for the content it can safely represent.

Seeing the result within a defined evidence boundary

Visual presentation enters at the end of a content operation, against the bytes eligible for publication. Check User Interface (Check UI) renders changed pages through browser automation using Playwright. Browser automation drives a real rendering engine at predefined viewport sizes, which lets the package inspect what a reader would receive on a compact laptop, a larger monitor, a tablet or a phone.

Changed pages are rendered over nine critical viewports by default, or all twenty governed viewports in a full review. A one-page request includes that page in every available locale. The checks cover what can be established deterministically: overflow, escaped or clipped content, duplicate identifiers, missing accessible control names, text contrast on determinable backgrounds, broken navigation, missing resources and runtime errors.

The evidence is useful precisely because its scope is stated. Check UI supplies deterministic browser evidence for the listed defects; a complete accessibility audit and human visual review cover composition, comfortable readability and whether an illustration communicates its intended idea. A generic overlap detector can also encounter legitimate movement, such as an in-page menu item entering or leaving the viewport as the reader scrolls. The system isolates that defensible false-positive class while continuing to report other overlaps.

A local run reports when a trustworthy live baseline is unavailable, keeping its evidence honest. Local review can target the whole estate or a chosen set of pages; the governed continuous-integration gate applies the candidate's changed-page scope before staging. Visual evidence informs the human decision, which remains the final judgement on presentation.

The principle is the same throughout: the system states exactly what it can prove and assigns the remaining judgement to its proper authority.

05The same thing must remain the same thing

A website written for people can tolerate repetition. The same course title may appear on four programme pages and on several faculty cards. A machine-readable graph must resolve whether those occurrences describe the same thing.

The relevant idea comes from the Semantic Web, introduced in more depth in DSTI's article Semantic Web & Linked Data: making the Web readable by machines: web resources can express documents, identified entities and typed relationships. A knowledge graph represents those entities as nodes and their relationships as edges. In this estate, much of that graph is published as JSON-LD inside static pages, so a separate graph database is unnecessary.

The shipped estate currently contains 11,128 typed JSON-LD objects carrying 11,162 type assertions and 1,849 unique identifiers. The relationships behind those numbers carry the meaning. A programme contains course instances. A course instance identifies an instructor. A faculty page expresses the reverse relation from a person back to the instances they teach or support. The programme and faculty views are therefore two directions through one graph.

Figure — the knowledge graph
KNOWLEDGE GRAPH · §5 One identifier per thing, referenced everywhere. IDENTIFY 785occurrences consolidate 126identities RELATE — TYPED EDGES Person · #prof-* CourseInstance instructor @reverse.instructor programme page → instructor faculty page → @reverse.instructor INTERPRET — ONE BOUNDARY, TWO VALIDATORS A bare { "@id": … } reference reads two ways: estate validator → valid reference to a node defined elsewhere in the graph; single-page validator → cannot infer the remote node's type. The declared boundary explains the difference. The estate is a graph a machine can resolve: the same faculty, courses and programmes the site describes, expressed as typed identities and relationships.
The knowledge graph: route-bound course occurrences collapse to governed invariants, while typed instructor links connect programme and faculty views.

The distinction between a course and a course instance is useful. “Mathematics for Data Science” can be one academic course identity while appearing in several programmes. Each programme occurrence is a course instance because it belongs to a particular educational context. That instance may link to the same governed course and to the professors teaching it. The model preserves both sameness and context.

Course identity exposed the difficulty most clearly. The estate once carried 785 route-bound course occurrences. Because their identifiers included the route where they appeared, the same course could look like several different courses to a machine. A governed migration reconciled those occurrences into 126 semantic course identities, recorded through 197 authority entries. The migration made course identity route-independent.

This required more than matching strings. Two labels can name the same course even when punctuation or an old course code differs. Two courses can carry similar labels and still be academically distinct. Direction of Studies may deliberately assign different codes across programme histories. Some old codes were duplicated across clearly different courses and had to be corrected at the source. An approved migration authority resolved those cases through academic meaning as well as string evidence.

The identifiers are expressed as web identifiers. An Internationalized Resource Identifier (IRI) extends the idea of a Uniform Resource Identifier (URI) to international character sets and can identify an entity independently of whether it is a conventional page. In practice, DSTI uses stable https://dsti.school/... identifiers with fragments for courses, people and instances. Every locale uses one shared course @id for the same academic course, while its local course instances retain their programme and language context.

This point matters because a locator and an identity have distinct roles. data-dsti-element-id locates a governed content element in maintained source. data-dsti-source-id records its lineage from the English source. A JSON-LD @id identifies the academic entity described by that content. Keeping those roles distinct preserves the meaning of the data.

The same work brought Faculty identities into the DSTI TechBlog. Article bylines that can be reconciled through the faculty authority now reuse the same faculty identifiers, replacing earlier page-local Person fragments. External contributors retain separate identities because the faculty graph governs members of the DSTI faculty.

The professor-course relationship required a vocabulary-valid reverse edge. Schema.org supplies instructor on CourseInstance; its vocabulary has no general Person.teaches property. JSON-LD's @reverse syntax expresses the inverse from the Faculty page. There, @reverse.instructor connects the Person to the typed course instances they teach or support. The forward and reverse views therefore agree through one valid Schema.org property.

The graph reports its present precision. Two faculty identifiers still carry accepted display-name variants, and a small set of article structures typed as courses needs a cleaner semantic model. The authority makes those edges visible enough to improve through evidence.

Why two validators can disagree

The World Wide Web Consortium (W3C) develops many of the standards on which the Web is built. Schema.org supplies a widely used vocabulary for structured data. A linked-data validator and a search-oriented single-page validator can nevertheless look at different boundaries.

A linked-data validator may accept a bare @id as a reference to a node defined elsewhere in the graph. A validator inspecting one page in isolation may see only an untyped object because its boundary ends at that page. The public markup now supplies the type needed by that single-page boundary, while the internal identity gate distinguishes a typed reference from a duplicate definition.

The design question comes first: is the node a new definition, a reference to an existing identity, or a local instance of a shared course? Once the boundary is settled, each validator can enforce the part it is capable of seeing; a green result then confirms the model already chosen by the authority.

The graph therefore follows the same three-part pattern as the rest of the system. The authority records identities and approved equivalences. The boundary distinguishes entities, occurrences and source elements. The gates check uniqueness, cross-locale identity, professor-course symmetry and Schema.org validity.

The authority supplies the design. Each validator enforces its consequences at a different boundary.

06The machinery should recede from the editor

The repository is essential to the system, while the person editing content should experience a clear content operation. That division shaped manager2.

Editors, publishers and platform administrators receive a role and a governed command surface. A primitive is one bounded operation with declared inputs, preconditions, effects and evidence: prepare a candidate, refresh a directory, publish media, take a live snapshot, restore it, or deploy. Branch creation, candidate assembly, staging and release remain present as mechanisms behind those operations, handled by the package itself.

Figure — manager2 and ports
MANAGER2 · §6 Primitives you drive; boundaries you can prove. CONTROL PLANE — DENY-BY-DEFAULT 18 local-content · run in a local session prepare update-content admissions partner-directory check-ui + 13 more 10 automation-only · refused locally → routed to CI deploy staging-publish staging-review restore-live ✕ refused in a local session provision — audited administrator break-glass (no CI job) The gate is a CI execution role, attested by injected context — not an env var, not a person's privilege. Human SSO privilege never becomes routine CI; rare break-glass remains explicit and audited. DATA LAYER — PORTS & ADAPTERS operationalcode PORT an agent record · the partner directory DRIVERHubSpot (today) futuredriver Principle 4: abstract around the domain concept — the estate owns the contract; the vendor is today's driver. manager2 publishes 28 governed primitives; the two boundaries above are what make "no action, and no data source, a hostage" — provable.
manager2: local-content and automation-only operations separated in the control plane; domain ports separate estate logic from today's data providers.

The command surface contains 28 governed primitives. Eighteen are available for local content work; ten run exclusively in automation. Local dispatch is deny-by-default: an attested pipeline identity supplies the execution context for routine promotion, while a human Single Sign-On (SSO) role remains a human session regardless of its privileges. Single sign-on lets one authenticated identity reach several systems; the separate execution-context check establishes whether the caller is release automation.

Rare estate provisioning has its own deliberately explicit route. As an occasional administrative bootstrap, it uses an audited Platform-Administrator break-glass operation. Routine content delivery stays in its pipeline, while rare provisioning stays visibly exceptional.

The machine-readable descriptor gives agents the same view of the command surface: arguments, preconditions, effects, execution context and receipts. It resembles the Model Context Protocol (MCP) shape used to describe tools to language-model clients, because that structure is efficient for agent interaction. It remains a descriptive manifest; governed commands retain all execution authority.

That separation matters. A drift test compares the descriptive manifest with the live registry, ensuring that every new primitive is documented and every retired primitive disappears from the advertised surface. The schema also requires every primitive to declare whether it is local-content or automation-only.

The same decoupling appears below the command surface. An Application Programming Interface (API) defines how software asks another system for data or actions. It is tempting for operational code to speak directly in one provider's fields: fetch a HubSpot object, read its properties, render them. That is quick, but it lets the provider's data model become the school's model.

The package instead uses the logic of the adapter design pattern, often described here as ports and adapters. The estate asks for an agent record or a partner directory in the school's domain language. That request is the port. HubSpot is today's driver or adapter behind it. Tests can replace the driver with a hand-written record source and render the same partner content independently of a live HubSpot connection.

This costs more code than calling the provider directly. In return, the school defines its partner data through the port while the current storage vendor remains a replaceable driver.

The same rule applies to source control. Amazon Web Services (AWS) CodeCommit is canonical because the organisation chose it as the current Git authority. GitHub is its read-only projection for visibility and collaboration, preserving one deployment authority. It also provides an issue-tracking surface through which readers and collaborators can submit bug reports and change requests, complementing CodeCommit's canonical role. A future provider change would require a new driver and operating route while the definition of a release stays stable.

The frozen public system snapshot has a separate purpose from that maintained projection. The projection belongs to the continuing release process. The snapshot is an archived, deliberately inert exhibit of one publication point: its fixed history and public-education purpose preserve the continuing package as the sole operational authority.

The first pipeline failed by making every internal proof into an operator ceremony. It collected receipts, hashes and bindings faster than a human could understand what decision each one protected. Safety mechanisms had begun to obscure the operational model.

The correction placed each proof where it belongs. One snapshot records the previous live estate. Preparation replaces the previous candidate and presents one current attempt. The last successful preparation is the candidate eligible for publication. Successful deployment cleans owned temporary material and advances the Git authorities. Failed deployment restores the captured predecessor and leaves that snapshot available for an operator-requested rollback.

One repository is canonical. Local work is content-only. Automation owns public estate writes. Git remains everywhere beneath the surface, while the editor works through the content operation.

Good governance is measured by the important failures the system can prevent while the operator remains focused on the decision at hand.

07Review must mean ship

The final promise is the most concrete: the edition approved is the edition published.

To understand the mechanism, it helps to unpack Continuous Integration and Continuous Delivery (CI/CD). Continuous integration means that changes are integrated and checked through a shared automated process, giving the organisation evidence beyond one contributor's machine. Continuous delivery means that a validated candidate can move through a repeatable path towards publication. Here, “continuous” describes readiness and repeatability; the final release remains a human decision.

Local editing and public release are therefore separate lifecycles.

  1. An editor changes maintained source on a content branch.
  2. The governed preparation rebuilds the whole estate and runs its content, semantic and structural gates.
  3. The editor reviews the affected locale set, including any chosen visual checks.
  4. The branch is pushed to the canonical repository (AWS CodeCommit).
  5. AWS CodePipeline runs its hermetic pre-check in AWS CodeBuild — resolving the governed toolchain and packages from AWS CodeArtifact — rebuilds the estate, then runs candidate- and browser-dependent tests before publishing to a private staging estate.
  6. The publisher reviews that staged edition and gives the sole human go-live approval.
  7. The deployment pipeline (AWS CodePipeline) repeats both AWS CodeBuild test phases around its rebuild and verifies the approved candidate before touching the public estate, then advances the canonical release and its read-only GitHub projection.
Figure — the CI/CD process
CI/CD PROCESS · §6–§7 One authority, two governed lifecycles. LOCAL — CONTENT-ONLY (editor + agent) edit local_website — build · validate · check-ui manager2 prepare local_website has no prepare verb — prepare is a manager2 primitive. push `content/<actor>` branch → CI writes the estate CI STAGING BUILD — AUTOMATION (freshness-gated) freshness gate ci-precheck snapshot-live prepare ci-postcheck staging-review (conflict-gated) record + advance staged · digest "staged for review" card Green phases partition the complete registered test surface: before and after candidate assembly. PUBLISHER APPROVAL — the only human decision GO-LIVE PIPELINE — AUTOMATION (headless, after approval) authority.check ci-precheck snapshot-live prepare ci-postcheck verify-staged-digest staging-publish verify-deploy-point deploy release + tag · GitHub mirror Both pipelines run every registered test in the earliest phase where its real inputs exist. Staging remains mandatory; digest and deploy-point checks bind publication to the reviewed candidate. Green steps are verification phases or publication guards; each precedes the mutation it governs. One authority; Git is present throughout but recedes from editors — publisher approval is the only human gate.
The CI/CD process: local content work becomes a staged candidate; publisher approval starts a headless go-live pipeline guarded by staged-content and deploy-point checks.

Staging is the review boundary. The candidate there has a content digest—a value calculated from its bytes using a cryptographic hash function. A good hash makes accidental or deliberate changes overwhelmingly likely to produce a different digest. Comparing digests is therefore a compact way to establish that two assembled estates contain the same reviewed content.

The go-live pipeline establishes fresh evidence for the earlier build. It rebuilds under the governed runtime, compares the new candidate digest with the staged edition, republishes the reviewed bytes to staging, verifies the deploy point, captures the rollback boundary and only then applies the live estate.

The static architecture helps. The public estate is a stable set of versioned files held in object storage and distributed through a Content Delivery Network (CDN); review and publication therefore operate on immutable file candidates. The deployment can capture the current live version, apply the new set, and restore the previous set if the transaction fails.

The infrastructure boundary accepts a successful provider upload. The stronger proof belongs earlier, where the assembled candidate is compared with the reviewed one. Earlier object-by-object read-back added operational weight while contributing little additional safety, so the present design keeps the evidence at the boundary where it is strongest.

Repeatable staging within an explicit concurrency boundary

Review is iterative, so staging must be repeatable. An editor may stage, discover a defect, correct it and stage again within the same intended public version.

That creates a subtle race. The staging branch advances, but an older approval can remain visible long enough to be actioned. The current deploy performs a self-check before checkout and admits only an edition that matches the current staged state. A stale approval produces a clear supersession message in place of a low-level Git failure.

The remaining operational rule is narrow and explicit: approve go-live after the current staging build has completed. The self-check prevents the known stale-edition failure, while this sequencing rule covers the small interval before staged state settles. This is a good example of honest engineering language: a precise qualification strengthens a guarantee by defining its real boundary.

The runtime is part of the candidate

Repeatability also depends on the tools that assemble the files. The same source becomes repeatable when it is paired with the same governed interpreter, browser engine and content generator.

The Python operator runtime is governed and hash-locked. Browser checks use their own Playwright environment. HTML validation uses a governed Java runtime. ContentInventory uses the governed .NET toolchain. macOS, Linux and Windows share the content-editing path. Build and deployment run on the environments in which the complete toolchain has been accepted; Windows remains within its proven content-editing scope.

This is an evidence-based acceptance boundary for Windows. It can provision the user-level media tools it needs—FFmpeg, ImageMagick and the AV1 Image File Format (AVIF) tools through the Scoop package manager—and can run the supported editing commands. The build and release environments remain the ones in which the full toolchain has been proven. Evidence will lead any future expansion of that boundary.

What the test count reveals

The test registry contains 162 registered test modules, divided by the moment at which their required inputs exist. A module groups related test cases, so module and test counts are different: the complete verification runs 1,292 test cases in the pre-check and 283 in the post-check.

The first phase, ci-precheck, runs 136 modules before prepare. These tests are hermetic: controlled inputs and injected effects make them independent of a live provider, a browser or an already assembled website. They can expose a defect before the expensive build begins.

The second phase, ci-postcheck, runs the remaining 26 modules after prepare has created the publication candidate and provisioned the browser runtime, ahead of any staging or deployment estate write. It includes build, translation, acceptance and browser checks whose meaningful input is the assembled candidate. Both the staging build and the go-live build run the two phases in this order.

A machine-readable completeness contract makes the division a complete partition. Every registered module belongs to exactly one phase: the two disjoint sets cover the whole registry. Before that contract, 26 meaningful modules existed in governed suites outside both CI phases.

The count describes coverage; the behaviour each test proves determines its quality. A thousand weak tests can protect less than one well-designed behavioural test. The useful question is what failure each family is intended to expose. Across the two phases, the registry includes, among others:

The division follows technical input boundaries. Every meaningful proof runs before an estate write, in the earliest phase where its real inputs exist. A stale test is corrected, while a test whose purpose has ended is retired from the registry.

Activating the full surface demonstrated why the distinction matters. Several candidate-dependent tests had been reading built output from maintained source and therefore exercising only a small residue—or skipping the proof entirely. Once CI actually ran them after preparation, pointing the tests at the candidate restored their intended evidence and preserved the valid content. Registration said that a test existed. Execution against the right boundary established that it proved something.

This is the point at which “works on my machine” stopped being relevant. The meaningful statement became: the same governed operation produced the reviewed candidate and the publication candidate, and the system proved their relationship before writing the estate.

08What the organisation keeps

The visible result of this work is still a static website, and that simplicity is a strength. A visitor receives ordinary pages quickly while the system that produced them recedes from view.

The important result is that the school's decisions now live in shared, durable authorities.

The language variants are recorded. The boundary between translated explanation and canonical academic substance is recorded. The identity of a course and its relation to a professor are recorded. The roles that may edit, approve and administer are recorded. The difference between local work and deployment automation is recorded. The conditions under which publication must stop are recorded.

Some of those decisions are code. Some are authority files, schemas, tests or operating documents. They are all deliverables. Together with working software, they tell the next contributor why its boundaries exist.

This is also why documentation is more than commentary around the “real” package. A stale command in an operator guide can cause a failed release. An inaccurate description of staging can encourage an approval during the one interval in which it is unsafe. A machine-readable primitive descriptor can mislead an agent as effectively as a broken function can mislead a program. Documentation has to be compared with the implementation and, where practical, structured enough for tests to detect drift.

The route to that conclusion included several useful corrections. Documentation sweeps found that staging-publish had been described as the disposable review push, a role that belonged to staging-review. Later sweeps refined when the staged pointer was committed and what happened after a Git failure. The code had often been correct; the prose needed to catch up.

The durable correction moved the lifecycle description into structured data, constrained by a schema and checked against the live primitive registry and the CI build specifications. A semantic guard now verifies that automation-only primitives are presented through their automation route. Independent recovery capabilities are represented as independent paths, giving an agent their intended relationships and purposes clearly.

That history is worth retaining because it says something about technical debt. Drift can emerge in current prose as readily as in old code, and a polished explanation can carry an error with confidence. The practical answer is to identify operational claims with material consequences and give those claims a structured authority where doing so reduces real risk, while prose continues to explain their purpose.

A public exhibit with one immutable purpose

There was one final test of that reasoning: could the system itself become a safe, transparent and genuinely useful public exhibit?

Most of the visible estate was already public in the ordinary sense. A browser downloads its HTML, CSS, JavaScript, structured data and media references. Anyone can inspect the pages the system ships. Publishing the repository reveals a broader view: the maintained source, the generators, the authorities, the tests and the design of the release machinery appear together. That is the material needed to understand both what the site contains and how the organisation tries to keep it coherent.

A safe publication required a purpose-built copy. The private package also contained live provider bindings, estate topology, repository and pipeline identities, staging routes and one governed confidential edge function. The machine-readable snapshot boundary records the resulting non-operational purpose and its limitations. The design remains intelligible through typed placeholders and inert surfaces, while the operational map stays within its governed private boundary.

Preserving the infrastructure's shape was essential to an honest account of the mechanisms this article describes. The public copy therefore retains the architecture in an inert form. Live identifiers become typed illustrative placeholders. Provider-facing primitives and direct administrative entry points stop at the public-snapshot boundary, before identity, credential or network access. Included build specifications recognise the same marker immediately, and the infrastructure templates carry an immutable false deployment condition.

The confidential CloudFront Function received a stricter boundary. Preparation left its original source unread. The path remains so that the architecture can still be followed, while its contents are a labelled inert substitute returning a Hypertext Transfer Protocol (HTTP) 503 response. The snapshot demonstrates the edge function's architectural place while its behaviour stays confidential.

Public content followed a byte-for-byte fidelity rule. The public redaction manifest identifies the six content roots and records them as byte-identical to the source tree. They cover the maintained website, the shipped estate and the awareness, facts, information and Sophia collateral families. The same manifest records that the 363 retained redirect entries resolve only to public DSTI routes, clear of staging, authentication and administrative locations. The Dsti.ContentInventory workbook was inspected as a document container and found clear of macros, external connections, embedded objects, unpublished email addresses and local filesystem paths.

The result was then tested as its own object, with evidence specific to the public copy. A bounded public-snapshot suite checks the inert execution boundary, schemas, redacted CloudFront capture, filesystem hygiene and provider-independent build and content contracts. Its recorded verification result contains 108 passing tests across 15 modules. The full generator was also run in a disposable isolated-build layout; 284 pages reached the complete estate-consistency gate and the build completed independently of provider access. A separate residue audit found the publishable copy clear of credential, private-key, token and private-identifier matches.

Only then did the copy receive a Git history: one new parentless root commit containing solely the public tree. The public repository is archived, keeps its workflows inactive and retains all rights. Its purpose is technical transparency and education. The continuing package remains private and canonical; the exhibit stays fixed at that publication point.

The exercise reproduced the article's leading pattern one last time. The boundary separated material needed to understand the system from material that could reconnect it to the live estate. The authority was the recorded source commit, the redaction manifest and the public snapshot's single immutable tree. The gate was the combination of content-equivalence checks, non-operability tests, container inspection and sensitive-data scanning that had to pass before the repository became public.

“Make everything public” was therefore analysed as an organisational command: make the engineering inspectable, preserve the evidence needed to learn from it, and preserve one clear operational authority.

Where human judgement leads

Maintenance continues.

Human readers judge naturalness beyond the translation gates. The graph still contains identities that can be improved. People decide whether typography is pleasant beyond browser automation. A faculty-course reconciliation can reveal that Direction of Studies used the same code for different courses; academic authority decides the new code. The test surface has a cost. Documentation can drift and must be reread against the implementation.

Governance contains particular risks and makes the remaining uncertainty visible.

What it changes is where the uncertainty sits. A routine content editor can rely on the package to carry the release process. A publisher receives direct evidence that staging and production contain the same candidate. A future engineer can inspect unresolved relationships directly at their authority. The organisation can decide where human judgement is required because the mechanical parts have been separated from it.

The teaching turn

That is why this system belongs in the classroom.

ADIS teaches students to begin with activities, events, data, stakeholders, responsibilities and constraints, then choose the implementation that serves them. The website is now a live case study in that discipline. And in its 2026 reality: LLM-assisted.

“Meet people in their own language” became a locale model, a translation boundary and cross-estate gates. “Give the organisation a shared memory” became a governed repository, roles and explicit operating surfaces. “The same professor and course must remain the same thing” became an identity authority and a knowledge graph. “What we approve is what we publish” became a staged digest, a publisher decision and a controlled deployment path.

In each case, the technology followed the promise:

Organisational promise Boundary Authority Gate
Meet readers in their language while preserving the programme Localisable explanation versus canonical academic substance Locale and terminology authorities Translation, route and metadata coherence
Let editors concentrate on content while automation handles deployment Local content operations versus automation-only estate writes Primitive registry and identified content model Execution-context and edit-session checks
Keep repeated people and courses as one entity Entity identity versus page occurrence Faculty and course identity authorities Uniqueness, symmetry and Schema.org checks
Publish exactly what was reviewed Local edit, staged candidate and live estate Canonical Git state plus staged content digest Candidate, deploy-point and rollback checks
Make the engineering inspectable within a safe public boundary Public system explanation versus live estate bindings Immutable public root commit and redaction manifest Content equivalence, inert-operation and sensitive-residue checks

The table makes the leading thread visible while the system continues to evolve. Boundaries keep each promise precise. Authorities give decisions a durable home. Gates turn those decisions into conditions the system actively protects.

Part 1 described the three-week rebuild that made a coherent static estate possible. Part 2 is about what happened when that estate had to become organisationally dependable. The second problem was less visible and, in many ways, more difficult. It meant building useful controls and retiring ceremony; adding tests and correcting those that had mistaken local expression for factual drift; publishing structured data and deciding what the entities actually were; then making the source visible through a public exhibit whose operation remains safely inert.

The site became an engineering system when the organisation's promises acquired boundaries, authorities and evidence—and when the system learned to state the exact scope of every proof.

The code came last. It should remain that way.