AISE502/project_exercise/project_exercise.tex

540 lines
27 KiB
TeX

\documentclass[12pt,a4paper]{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[english]{babel}
\usepackage{geometry}
\geometry{margin=2.5cm, headheight=14.5pt, footskip=1.8cm}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{fancyhdr}
\usepackage{tcolorbox}
\tcbuselibrary{breakable}
\usepackage{enumitem}
\usepackage{microtype}
\usepackage{booktabs}
\setlength{\emergencystretch}{3em}
\renewcommand{\texttt}[1]{{\ttfamily\hyphenchar\font=`\-\relax #1}}
\definecolor{codegreen}{rgb}{0,0.6,0}
\definecolor{codegray}{rgb}{0.5,0.5,0.5}
\definecolor{codepurple}{rgb}{0.58,0,0.82}
\definecolor{backcolour}{rgb}{0.95,0.95,0.92}
\lstdefinestyle{pythonstyle}{
backgroundcolor=\color{backcolour},
commentstyle=\color{codegreen},
keywordstyle=\color{blue},
numberstyle=\tiny\color{codegray},
stringstyle=\color{codepurple},
basicstyle=\ttfamily\footnotesize,
breaklines=true, keepspaces=true,
numbers=left, numbersep=5pt, tabsize=4, language=Python
}
\lstdefinestyle{promptstyle}{
backgroundcolor=\color{backcolour},
basicstyle=\ttfamily\footnotesize,
breaklines=true, keepspaces=true,
frame=single, rulecolor=\color{codegray}, tabsize=4
}
\lstset{style=pythonstyle}
\newtcolorbox{taskbox}[1][]{colback=blue!5!white, colframe=blue!75!black,
title={#1}, fonttitle=\bfseries, breakable, before upper=\raggedright}
\newtcolorbox{hintbox}{colback=yellow!5!white, colframe=yellow!50!black,
title=Hints \& Tips, fonttitle=\bfseries, breakable, before upper=\raggedright}
\newtcolorbox{warningbox}{colback=red!5!white, colframe=red!60!black,
title=Common Mistakes \& Pitfalls, fonttitle=\bfseries, breakable, before upper=\raggedright}
\newtcolorbox{conceptbox}[1][]{colback=green!5!white, colframe=green!50!black,
title={#1}, fonttitle=\bfseries, breakable, before upper=\raggedright}
\newtcolorbox{contextbox}[1][]{colback=gray!5!white, colframe=gray!60!black,
title={#1}, fonttitle=\bfseries, breakable}
\pagestyle{fancy}
\fancyhf{}
\fancyhead[L]{AISE502 -- AI in Software Engineering II}
\fancyhead[R]{Project: Portfolio Intelligence Platform}
\fancyfoot[L]{\thepage}
\fancyfoot[R]{\includegraphics[height=0.9cm]{../FHGR_Logo_small}}
\renewcommand{\headrulewidth}{0.4pt}
\begin{document}
\begin{titlepage}
\centering
\includegraphics[width=0.5\textwidth]{../FHGR_Logo_Large}\\[1cm]
{\Huge\bfseries AI-Augmented Portfolio\\[0.3cm] Intelligence Platform\par}
\vspace{0.8cm}
{\Large AISE502 -- AI in Software Engineering II\par}
\vspace{0.5cm}
{\large Autumn Semester (5th Semester)\par}
\vspace{1.2cm}
{\large Semester Group Project\par}
\vspace{0.4cm}
{\normalsize Language: Python 3.11+ \quad$\cdot$\quad Architecture-first \quad$\cdot$\quad Services with contracts + AI agents\par}
\vfill
{\small Analysis \& advisory only --- no trading, no real money.\par}
\end{titlepage}
%====================================================================
\section{Overview and Goals}
The goal of this project is to design, build, and operate a \textbf{modular,
AI-augmented analysis platform for stock portfolios}. The platform ingests
\emph{structured} external data (market prices) and \emph{unstructured} external data
(company news and web reports), turns both into decision-relevant information, computes
quantitative risk, performance, and optimisation figures, and exposes the results through
a small set of cooperating services driven by an orchestrated multi-agent layer. Whether those
services ship as one modular monolith or as several deployables is not prescribed here: it is
the architecture decision you take in week~6 with the lecture's three-stage match and defend
in week~14.
This is a \textbf{Software Engineering II} project: the centre of gravity is
\emph{architecture}---how you structure a system so that it meets its quality attributes
and stays maintainable while one part of it (the news understanding) is non-deterministic,
fallible, and costly. AI appears in two roles throughout the project: as a \emph{tool} you
build the system \emph{with}, and as a \emph{component} that lives \emph{inside} the system.
\begin{conceptbox}[The single most important rule]
The AI agents may only \textbf{obtain and interpret} quantitative values \emph{through the
deterministic services} --- they must \textbf{never compute} a risk number, a return, or an
allocation themselves. An agent that ``estimates'' a volatility is an architecture defect.
This separation of deterministic from non-deterministic system parts is the core engineering
lesson of the course, and it is graded.
\end{conceptbox}
\subsection{What the platform does}
\begin{enumerate}[nosep]
\item Ingest \textbf{market prices} from a live API (e.g.\ Yahoo Finance) with a
mandatory cache/snapshot fallback.
\item Ingest \textbf{company news / web reports} (unstructured text).
\item Use an \textbf{AI component} to turn news into structured insights (e.g.\ sentiment,
affected tickers, event type) --- validated against a domain ontology.
\item Compute \textbf{risk, performance, and optimisation} figures in deterministic
services (formulae and test vectors are provided to you).
\item Provide an \textbf{orchestrated multi-agent advisor} that combines the above into
portfolio insights and explanations.
\item Expose everything \textbf{API-first}, with a thin dashboard (e.g.\ Streamlit) only
for demonstration.
\end{enumerate}
\begin{contextbox}[Why build this?]
This project forces the full architecture-and-engineering arc: you derive a service
architecture from a domain ontology, design contracts between services, harden the system
against unreliable external data, integrate non-deterministic AI behind stable interfaces,
and evaluate, observe, and scale it. You will \emph{experience} first-hand why
non-deterministic components demand discipline --- and you will use modern agentic
development tools to build it, while keeping a critical eye on what they produce.
\end{contextbox}
%====================================================================
\section{Functional Requirements}
Each requirement names example \textbf{services} and their responsibilities. The exact
class and module decomposition is part of \emph{your} architectural work --- the names below
are guidance, not a prescription.
\subsection{Market Data (deterministic)}
\begin{taskbox}[Features]
\begin{itemize}[nosep]
\item Fetch historical and recent prices for a configurable set of tickers.
\item Use a live API with a \textbf{mandatory} cache/snapshot fallback when the API is
unavailable or rate-limited.
\item Provide a clean, versioned interface to downstream services.
\end{itemize}
\end{taskbox}
\begin{taskbox}[Services / Responsibilities]
\begin{itemize}[nosep]
\item \texttt{MarketDataService}: retrieval, caching, normalisation of price series.
\item Must expose a stable contract independent of the upstream provider's format.
\end{itemize}
\end{taskbox}
\subsection{News Ingestion \& AI Insight Extraction (non-deterministic)}
\begin{taskbox}[Features]
\begin{itemize}[nosep]
\item Ingest unstructured company news / reports for the portfolio's tickers.
\item Use an LLM to extract \textbf{structured insights}: sentiment, affected tickers,
event type, short summary.
\item Validate every extracted insight against the domain ontology (valid ticker?
valid sector? plausible event type?).
\end{itemize}
\end{taskbox}
\begin{taskbox}[Services / Responsibilities]
\begin{itemize}[nosep]
\item \texttt{NewsIngestionService}: fetch and store raw news with provenance.
\item \texttt{ResearchAgent}: LLM-based extraction returning a strict, schema-validated
\texttt{Insight} object. This is an \textbf{Anti-Corruption Layer}: the rest of the
system never sees raw LLM text, only validated \texttt{Insight}s.
\end{itemize}
\end{taskbox}
\subsection{Quantitative Analysis (deterministic)}
\begin{taskbox}[Features]
\begin{itemize}[nosep]
\item Compute portfolio \textbf{performance} (returns, cumulative return, Sharpe ratio).
\item Compute \textbf{risk} (volatility, Value-at-Risk).
\item Compute a \textbf{portfolio optimisation} (mean--variance / Markowitz).
\item Formulae and reference test vectors are provided --- you implement the
\emph{services and tests}, not the financial theory.
\end{itemize}
\end{taskbox}
\begin{taskbox}[Services / Responsibilities]
\begin{itemize}[nosep]
\item \texttt{PerformanceService}, \texttt{RiskService}, \texttt{OptimizationService}.
\item Each is \textbf{pure and deterministic}: same input $\rightarrow$ same output. These
are the services your tests pin down exactly and your AI is evaluated against.
\end{itemize}
\end{taskbox}
\subsection{Portfolio State}
\begin{taskbox}[Features / Services]
\begin{itemize}[nosep]
\item \texttt{PortfolioService}: holdings, positions, transactions (in-memory or simple
persistence is sufficient).
\item Provides the current portfolio composition to the analysis services and the advisor.
\end{itemize}
\end{taskbox}
\subsection{Multi-Agent Advisor (orchestration)}
\begin{taskbox}[Features]
\begin{itemize}[nosep]
\item An \texttt{AdvisorAgent} orchestrates specialised sub-agents to answer
portfolio questions and produce explained recommendations.
\item Sub-agents communicate only through \textbf{service contracts}, never by sharing
internal state.
\end{itemize}
\end{taskbox}
\begin{taskbox}[Services / Responsibilities]
\begin{itemize}[nosep]
\item \texttt{AdvisorAgent} (orchestrator), \texttt{ResearchAgent} (news $\rightarrow$
insights), \texttt{RiskAgent} (calls \texttt{RiskService}, interprets), and
\texttt{OptimizationAgent} (calls \texttt{OptimizationService}, explains).
\item Agents \emph{interpret and explain} numbers; services \emph{compute} them.
\item The lecture script's worked example (Part~V, Section~44.1) describes the same
workflow with the role names \emph{document analyst} ($\approx$ \texttt{ResearchAgent}),
\emph{portfolio quant} ($\approx$ \texttt{RiskAgent} / \texttt{OptimizationAgent}) and
\emph{compliance checker} ($\approx$ the ontology guard) -- one design, two vocabularies.
\end{itemize}
\end{taskbox}
\subsection{Interface (API-first, thin UI)}
\begin{taskbox}[Features]
\begin{itemize}[nosep]
\item A clean HTTP/JSON API is the primary product surface.
\item A thin dashboard (e.g.\ Streamlit) for demonstration: show the portfolio, the
computed figures, and the advisor's explained recommendation.
\item The UI must contain \textbf{no business logic} --- it only calls the API.
\end{itemize}
\end{taskbox}
%====================================================================
\section{Architecture: From Ontology to Services}
Before implementing, derive your architecture from the domain. This is the
\emph{traceability chain} you practised conceptually in AISE501 --- now you build it for real.
\begin{conceptbox}[Derivation chain]
Domain understanding $\rightarrow$ Domain model $\rightarrow$ \textbf{Ontology} (asset
classes, sectors, rules) $\rightarrow$ \textbf{Bounded contexts} $\rightarrow$ Services with
contracts $\rightarrow$ AI agents behind anti-corruption layers $\rightarrow$ evaluation,
observability, hardening.
\end{conceptbox}
\subsection{Reference architecture}
The system follows a service-oriented split -- a \emph{logical} split into services with
contracts; the deployment cut (one modular monolith, several deployables, or a hybrid) is the
outcome of your match. Deterministic services form a trustworthy core;
the non-deterministic AI layer sits on top and may only \emph{read} the core through its
contracts.
\begin{lstlisting}[style=promptstyle]
+-----------------------------------------------------------+
| Thin Dashboard (Streamlit) --- API-first, no logic |
+----------------------------+------------------------------+
| (stable HTTP/JSON API)
+----------------------------+------------------------------+
| Multi-Agent Layer (NON-DETERMINISTIC) |
| AdvisorAgent (orchestrator) |
| |-- ResearchAgent (news -> Insight) |
| |-- RiskAgent (calls RiskService) |
| +-- OptimizationAgent (calls OptimizationService) |
| LLM Gateway: ONE port for every model call -- |
| cost/latency per request, fallback chain (ADR-011) |
+-----------------------------------------------------------+
| DETERMINISTIC SERVICES (NO LLM INSIDE) |
| MarketDataService (live API + cache fallback) |
| NewsIngestionService(raw news + provenance) |
| PerformanceService (returns, Sharpe) |
| RiskService (volatility, VaR) |
| OptimizationService (mean-variance) |
| PortfolioService (holdings, positions) |
+-----------------------------------------------------------+
| Domain Ontology = architecture contract + guard rail |
+-----------------------------------------------------------+
\end{lstlisting}
\subsection{The ontology in two roles}
\begin{itemize}[nosep]
\item \textbf{As a contract (build time):} the ontology defines the bounded contexts and
drives the service boundaries and data models.
\item \textbf{As a guard (run time):} every AI-produced insight is validated against the
ontology before it is allowed into the system, suppressing hallucinated tickers,
sectors, or impossible events.
\end{itemize}
%====================================================================
\section{AI Integration: Contracts, Guards, and Evaluation}
\subsection{Anti-Corruption Layer around the LLM}
\begin{taskbox}[Requirements]
\begin{itemize}[nosep]
\item The LLM is reached only through the \texttt{ResearchAgent}, which returns a strictly
schema-validated \texttt{Insight}. No other code touches raw model output.
\item Use structured output / schema validation; reject or repair non-conforming responses.
\item Keep system prompts concise; separate persona, task, and data (use the prompting
techniques from AISE501).
\item \textbf{One LLM gateway}: every model call -- the \texttt{ResearchAgent}'s extraction as
well as the advisor's and sub-agents' calls -- goes through a single gateway behind a
port owned by the domain (the lecture's ADR-011). Domain code never imports a provider
SDK; the gateway records tokens, cost, and latency per request and holds the fallback
chain.
\item Every \texttt{Insight} carries a provenance reference to the stored news item, so that
the advisor's answers can cite their sources.
\end{itemize}
\end{taskbox}
\subsection{Guards against hallucination and failure}
\begin{taskbox}[Requirements]
\begin{itemize}[nosep]
\item Validate every insight against the ontology (valid ticker / sector / event type).
\item Apply resilience patterns to \emph{every} external call (market API, news API, LLM
API): timeout, retry with backoff, circuit breaker, and a defined fallback.
\item The system must degrade gracefully: if the LLM or a data API is down, deterministic
analysis must still work and the UI must say so.
\end{itemize}
\end{taskbox}
\subsection{Evaluation harness (mandatory)}
\begin{taskbox}[Requirements]
\begin{itemize}[nosep]
\item \textbf{Deterministic services:} pin them with exact tests against the provided
reference test vectors.
\item \textbf{Non-deterministic AI:} build an eval harness --- e.g.\ a small labelled set
of news items with expected sentiment/tickers, plus regression checks against
ontology axioms. Report accuracy and failure modes, not just ``it works''.
\end{itemize}
\end{taskbox}
\subsection{Building with AI tools (Axis A)}
\begin{taskbox}[Requirements]
\begin{itemize}[nosep]
\item The repository carries an agent instruction file (\texttt{AGENTS.md} / \texttt{CLAUDE.md})
that states the architecture rules an agent must respect; keep it as current as code.
\item Every architecture decision is an ADR: agents may draft it, a named team member signs it.
\item Agent-generated changes reach the main branch only through the CI gate: module-boundary
checks, the test suite, and -- for anything touching prompts or the gateway -- the eval
harness.
\item Your project handbook contains a one-page AI policy: permitted tools, provenance
labelling of generated code, review rules.
\end{itemize}
The graded artefact is not the generated code but the control system around it (Lecture~12);
the M6 reflection on where AI helped and hurt \emph{in building} draws on exactly this.
\end{taskbox}
\begin{warningbox}
\begin{itemize}[nosep]
\item \textbf{Never} let an agent compute or invent a numeric figure --- always route
through the deterministic service.
\item \textbf{Never} pass an unvalidated LLM response further into the system.
\item Do not call external APIs without a timeout and a fallback --- they \emph{will} fail
during your demo.
\item Do not put business logic in the UI; it belongs in services.
\item Treat news text as \textbf{untrusted input}: it is a prompt-injection vector.
\item Never hardcode API keys --- use environment variables / a \texttt{.env} file
excluded from version control.
\end{itemize}
\end{warningbox}
%====================================================================
\section{Mandatory vs.\ Distinction (Pflicht / K\"ur)}
\label{sec:distinction}
\begin{conceptbox}[Mandatory --- required to pass]
\begin{itemize}[nosep]
\item Architecture derived from the ontology, documented with ADRs and a C4-style diagram.
\item Deterministic services with full, exact tests against the reference vectors.
\item Orchestrated advisor with \textbf{2--3 specialised sub-agents} cooperating only via
service contracts.
\item Ontology guard on all AI insights; resilience against external-data outages.
\item Evaluation harness for the AI component; basic observability (cost and latency)
through the single LLM gateway.
\item The measurement contract of deliverable A2 (module-boundary check, eval threshold,
token-cost budget) wired into CI.
\end{itemize}
\end{conceptbox}
\begin{conceptbox}[Distinction --- for top grades]
\begin{itemize}[nosep]
\item \textbf{Autonomous planning}: the advisor decides itself which sub-agents/tools to
call rather than following a fixed pipeline.
\item \textbf{Self-repair loops}: e.g.\ ``news contradictory $\rightarrow$ fetch more
sources'' before answering.
\item \textbf{Model routing}: a small/cheap model for sentiment, a larger one for synthesis,
with cost/latency reported.
\item Deployment with CI/CD and richer observability (tracing).
\end{itemize}
\end{conceptbox}
%====================================================================
\clearpage
\section{Semester Plan and Development Milestones}
The project is organised in \textbf{two phases}, tightly synchronised with the lecture
(script Parts I--V). \textbf{Weeks 1--7 are the design phase}: the weekly two-hour exercise
slot is used to produce the requirements, study candidate architectures against the patterns
taught in the lecture, and decide and document your architecture. \textbf{Weeks 8--14 are
the implementation phase}: the exercise slot becomes a one-hour standup/coaching session,
and implementation happens mainly in self-study time. All design deliverables use the
methods of the lecture script: quality attribute scenarios with response measures, a utility
tree, the requirements profile $R(a)$, the three-stage match, an ADR with rationale, and a
measurement contract.
\begin{center}
\small
\begin{tabular}{@{}p{1.0cm}p{6.4cm}p{7.0cm}@{}}
\toprule
\textbf{Week} & \textbf{Lecture (script)} & \textbf{Project work} \\
\midrule
1 & Part I: decision problem, framework & Kickoff: teams, tooling, domain model, ontology draft \\
2 & Part I: twelve dimensions; scenarios, utility tree & Quality attribute scenarios with response measures \\
3 & Part I: capability profiles, fit, mini-match, ADR & $R(\mathrm{platform})$ finalised $\rightarrow$ \textbf{Deliverable A1} \\
4 & Part II: layered, modular monolith, hexagonal & Architecture study I (Fineract, Cosmic Python) \\
5 & Part II: microservices, event-driven & Architecture study II: edges, contracts, resilience \\
6 & Part II: pipes-and-filters, serverless; stepping back; class C10 & The match: three stages, decision, ADR draft \\
7 & Part IV: three cases, procedure, matrix; measurement contract & Solution design, design-review gate $\rightarrow$ \textbf{Deliverable A2} \\
8 & Part III: classes C1--C5 & Walking skeleton (start) \\
9 & Part III: classes C6--C9 & \textbf{Walking skeleton runs end-to-end} \\
10 & Part IV: hybrids, evolution, eight-step procedure & Deterministic services + exact tests \\
11 & Part IV: measurement contract in depth (fitness functions, DORA) & Resilience complete; \textbf{core fully tested} \\
12 & Part V: Axis A; Axis B (gateway, eval basics) & Advisor + sub-agents behind the gateway \\
13 & Part V: Axis B (security, orchestration economics) & \textbf{Eval harness in CI}; hardening; distinction work \\
14 & Synthesis (1 lesson) & \textbf{Presentations, architecture defence, peer reviews} (A3) \\
\bottomrule
\end{tabular}
\end{center}
\begin{taskbox}[M1 --- Requirements and Ontology (Weeks 1--3) --- Deliverable A1]
\begin{itemize}[nosep]
\item Domain model and ontology of the investment domain.
\item Quality attribute scenarios with response measures (at least eight scenarios, at
least three of them for the AI components: answer correctness, token cost per
request, provider migration -- Lecture~2); utility tree; the requirements
profile $R(\mathrm{platform})$ with weights, workload shape, and hard constraints.
\item Project and tooling setup (repository, environment, agentic dev tools).
\item \textbf{Deliverable A1 (end of week 3): requirements dossier.}
\end{itemize}
\end{taskbox}
\begin{taskbox}[M2 --- Architecture Decision and Solution Design (Weeks 4--7) --- Deliverable A2]
\begin{itemize}[nosep]
\item Study the open-source reference systems from the lecture; evaluate candidate
architectures for the deterministic core and the edges.
\item Run the three-stage match (knock-out and shape gate; veto with documented
mitigations; ordinal reading); record the decision as an ADR with rationale;
C4-style diagram.
\item Bounded contexts $\rightarrow$ service decomposition and contracts; measurement
contract (token budget, eval threshold, module-boundary checks); walking-skeleton
plan.
\item Set numbers in the contract. Reference values from the lecture's worked ADRs
(Lectures~3 and~11): eval pass rate $\geq 95\,\%$ on a versioned golden set, p95
latency $\leq 20$\,s for the advisory scenario, a token-cost budget per request at
p95, zero module-boundary violations.
\item \textbf{Deliverable A2 (end of week 7): architecture dossier + design-review
gate.} Production code starts only after the gate (exploratory spikes are allowed).
\end{itemize}
\end{taskbox}
\begin{taskbox}[M3 --- Walking Skeleton (Weeks 8--9)]
\begin{itemize}[nosep]
\item End-to-end thin slice running: \texttt{MarketDataService} delivers prices and a
\emph{minimal} \texttt{ResearchAgent} produces one validated \texttt{Insight}.
\item Stable API and a placeholder UI that calls it.
\end{itemize}
\end{taskbox}
\begin{taskbox}[M4 --- Deterministic Core and Resilience (Weeks 10--11)]
\begin{itemize}[nosep]
\item \texttt{Performance}, \texttt{Risk}, \texttt{Optimization} services implemented and
fully tested against the reference vectors.
\item Resilience patterns on all external calls; graceful degradation verified.
\end{itemize}
\end{taskbox}
\begin{taskbox}[M5 --- Multi-Agent Orchestration, Evaluation, and Hardening (Weeks 12--13)]
\begin{itemize}[nosep]
\item Week 12: advisor orchestrates 2--3 sub-agents through contracts, every LLM call
through the gateway (mandatory); ontology guard active on all insights.
\item Week 13: evaluation harness as a CI gate; report accuracy and failure modes;
observability of token cost and latency per request; an ADR that justifies the
chosen orchestration topology (task-signature table, Lecture~13) with its token
budget and eval threshold.
\item Threat model including prompt injection via news; basic hardening;
scaling/optimisation (caching, batching).
\item Optional Distinction work: autonomy, self-repair, model routing, CI/CD, tracing.
\end{itemize}
\end{taskbox}
\begin{taskbox}[M6 --- Presentation and Architecture Defence (Week 14)]
\begin{itemize}[nosep]
\item Present the system and \textbf{defend your architectural trade-offs}.
\item Reflect on where AI helped and where it hurt --- in building (A) and in the system (B).
\item Peer reviews: each team reviews the other teams' presentations and defences.
\item Be prepared to show one measurement-contract violation being caught by CI
(Lecture~11): a contract that has never failed has never been tested.
\end{itemize}
\end{taskbox}
\begin{hintbox}
\begin{itemize}[nosep]
\item Build the Walking Skeleton first thing in the implementation phase (M3, weeks
8--9) --- a thin end-to-end slice de-risks everything that follows.
\item Use the design phase fully: a decided architecture with contracts and a
measurement contract makes the seven implementation weeks sufficient; an undecided
one does not.
\item Pin the deterministic services with tests \emph{before} you trust any agent output.
\item Keep the deterministic core free of LLM calls --- this is the line that is graded.
\item Use a snapshot of market/news data so your demo and grading are reproducible even if
the live APIs misbehave.
\item Commit after each milestone; record architectural decisions as ADRs as you go.
\end{itemize}
\end{hintbox}
%====================================================================
\section{Assessment of the Project}
The project counts \textbf{50\,\%} of the module grade --- including the requirements dossier
(deliverable A1), the architecture dossier with ADR and measurement contract (deliverable A2),
the implementation, and the final presentation with architecture defence. The remaining
50\,\% is the written module examination (60 minutes, open book, closed internet).
Evaluation of the project emphasises:
\begin{itemize}[nosep]
\item \textbf{Architecture \& trade-offs} --- quality of decomposition, contracts,
deterministic/non-deterministic separation, ADRs.
\item \textbf{Robustness} --- resilience, guards, graceful degradation.
\item \textbf{Quality} --- tests for deterministic services, eval harness for AI.
\item \textbf{AI integration} --- correct anti-corruption layering and ontology guarding.
\item \textbf{Operation} --- observability of cost/latency.
\item Distinction criteria for top marks (see Section~\ref{sec:distinction}).
\end{itemize}
\vfill
\begin{center}\small
Fachhochschule Graub\"unden $\cdot$ Pulverm\"uhlestrasse 57 $\cdot$ 7000 Chur\\
\url{https://fhgr.ch/cds}
\end{center}
\end{document}