Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5d429ec
feat(server): expose practice-area standing, trend and review history
Aug 22, 2026
980b7f4
test(server): port practice tests onto main's observation vocabulary
Aug 22, 2026
6852b13
feat(server): derive practice and area standings from one rule
Aug 23, 2026
d3b311f
feat(server): let a practice count for more in its area
Aug 23, 2026
93edb01
refactor(server): name the area-detail package after what it holds
Aug 24, 2026
1afafdb
chore(server): regenerate the API artefacts after rebasing onto main
Aug 24, 2026
e1d94b6
refactor(server): drop the trend verdicts the evidence cannot carry
Aug 24, 2026
3cd8551
fix(server): restore an import main dropped and clear the imports nob…
Aug 25, 2026
30286b7
refactor(server): carry the practice surfaces onto enforced null safety
Aug 25, 2026
ff2e85a
refactor(server): count the runs that found nothing to judge
Aug 26, 2026
6ef75e8
feat(server): answer feedback with two questions instead of two mecha…
Aug 26, 2026
c6417c3
docs: keep the standing/trend diagram out of the repository
Aug 27, 2026
161c9fa
fix(server): register the area-guidance context and let reads answer …
Aug 27, 2026
19213f4
docs: drop two changesets that promise more than the branch delivers
Aug 27, 2026
a3ddd7c
fix(server): keep a comment that came without a resolution
Aug 27, 2026
b164e38
fix(webapp): regenerate the client after title became optional
Aug 27, 2026
c249080
refactor(server): standardize practice groups and feedback responses …
FelixTJDietrich Aug 27, 2026
d329c81
fix(release): preserve pending changeset filenames
FelixTJDietrich Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 7 additions & 0 deletions .changeset/a-practice-says-why-it-has-nothing-to-say.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"hephaestus": minor
---

Your practice feedback now lists every practice your workspace reviews, not only the ones that raised something. A practice with nothing to report says which kind of nothing it is: either no review has reached it yet, or the reviews ran and your work offered no relevant occasion. Those are different answers to "how am I doing here", and until now both looked like an absent row. Practices with actual feedback still come first, worst first; the quiet ones sort to the end.

A group's standing is now read straight off its practices, including the quiet ones, so the summary at the top of a group and the practices beneath it can no longer tell different stories.
5 changes: 5 additions & 0 deletions .changeset/an-answer-keeps-the-words-that-came-with-it.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hephaestus": patch
---

A comment written alongside "not helpful" is no longer lost. Explaining why a piece of feedback missed the mark, without also saying whether you addressed or disputed it, stored the text and then never showed it again — the next answer overwrote the reading with its own empty comment. The words now stay with the answer they came with.
2 changes: 1 addition & 1 deletion .changeset/areas-get-an-icon-and-criteria-render.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"hephaestus": patch
---

Creating or editing a practice area now lets you pick its icon and colour, the same way the instance library does. Left alone, both still follow the area's name.
Creating or editing a practice group now lets you pick its icon and colour, the same way the instance library does. Left alone, both still follow the group's name.

A practice's "What to look for" is written in markdown — the editor says so — and the read view now renders it. Headings, lists, emphasis and inline code used to reach you as literal `##` and `-` characters in one long paragraph of bold text.
2 changes: 1 addition & 1 deletion .changeset/calm-practices-adopt.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ Workspace administrators now choose which practices their workspace reviews, ins

Adding never starts sending feedback on its own. A practice Hephaestus can review starts at **Review before sending**, and a practice it cannot review stays **Off** until you connect what it reads.

You can also add a whole area at once. Hephaestus shows every practice it would add, reuse, or skip first, and applies the result in one step or not at all. Adding is refused if the library or your workspace changed while you were reading the preview, so you always act on what you saw.
You can also add a whole group at once. Hephaestus shows every practice it would add, reuse, or skip first, and applies the result in one step or not at all. Adding is refused if the library or your workspace changed while you were reading the preview, so you always act on what you saw.

Workspaces you already have keep everything in them, and a workspace that has never recorded a catalog installation still receives one at the next start, so nothing goes missing.
5 changes: 5 additions & 0 deletions .changeset/feedback-says-which-kind-of-good-or-bad-it-is.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hephaestus": minor
---

Each piece of practice feedback now says what kind it is: a behaviour you demonstrated, a trap you avoided, something harmful that was done, or something needed that was left out. Reading a strength no longer means guessing whether you did the good thing or steered clear of the bad one — and the two kinds call for different responses.
5 changes: 5 additions & 0 deletions .changeset/feedback-survives-an-interrupted-review.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hephaestus": patch
---

Feedback about a practice no longer disappears when a later review of the same work never got to that practice. A review that was skipped for partial evidence, refused, timed out or ran out of budget covers fewer practices than the one before it, and the untouched practices' earlier observations were being dropped as though the newer review had reconsidered them — so an interrupted review looked exactly like a fixed habit. A later review now replaces only what it actually re-examined. The same holds per person: a review that had something to say about one contributor no longer clears what an earlier one found about another. Re-reviewing the same work with the same practice still replaces the earlier verdict, as before.
2 changes: 1 addition & 1 deletion .changeset/one-recovery-for-a-stale-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"hephaestus": patch
---

When the library changes while you are reading an area's plan, the panel now stays open and shows you the refreshed plan, the same way a single practice already did. It used to close and leave you a message asking you to go and look at the area again.
When the library changes while you are reading a group's plan, the panel now stays open and shows you the refreshed plan, the same way a single practice already did. It used to close and leave you a message asking you to go and look at the group again.
7 changes: 7 additions & 0 deletions .changeset/practice-standing-feedback-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"hephaestus": minor
---

The application API can now answer where a developer stands in each practice group: the current standing and its guidance, how the group has developed across recently reviewed work, which kinds of work contributed feedback, a filterable observation history, and the complete review runs behind it. An undecided observation remains visible in that history without being presented as a verdict. Developers can also replace or delete their response to delivered feedback, recording whether it was helpful, how they handled it, and an optional explanation. Every endpoint answers only for the signed-in developer.

**Operators:** direct API callers must replace `/practice-areas` with `/practice-groups`, use the corresponding group schema and field names, replace `/practices/learner` with `/practices/reviewed`, and move from the older reaction endpoint to the combined response endpoint. Existing response history is preserved; `MIGRATION.md` lists the contract changes. The generated Hephaestus web client is updated in the same release.
5 changes: 5 additions & 0 deletions .changeset/practice-standing-recent-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hephaestus": minor
---

Where you stand on a practice now follows your most recently reviewed work instead of the whole 90-day record. Two problem-free pieces of reviewed work in a row are enough for a practice to read as going well again, so fixing a habit becomes visible within two reviews — and a problem on your newest piece of reviewed work registers just as quickly. How much of the work went well is counted rather than merely whether anything went wrong, so a single problem among otherwise clean reviews no longer weighs the same as a run of them. The list of feedback below the standing is unchanged: it stays the complete record of what the window raised, while the standing above it describes where things stand now.
5 changes: 5 additions & 0 deletions .changeset/practice-trend-evidence.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hephaestus": minor
---

A practice group now reports how it has developed by comparing its four most recent relevant pieces of reviewed work with the four before them. It shows improvement or decline only when that evidence supports a direction; otherwise it reports that the direction is unclear or that more reviewed work is needed.
2 changes: 1 addition & 1 deletion .changeset/removing-an-area-asks-what-to-keep.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"hephaestus": minor
---

Removing a practice area now asks what should happen to the practices in it: keep them and move them to Unassigned, or delete them together with the area. Deleting them also deletes their observations, and the dialog says so before you choose. Previously the practices were always kept, with no way to remove an area and its practices in one step.
Removing a practice group now asks what should happen to the practices in it: keep them and move them to Unassigned, or delete them together with the group. Deleting them also deletes their observations, and the dialog says so before you choose. Previously the practices were always kept, with no way to remove a group and its practices in one step.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ nosetests.xml
# OpenCode builder mission files (per-worktree, ephemeral)
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
**/out/
# Local document exports (plans, PDFs) — not part of the codebase
output/
parts/
# pdm
#pdm.lock
Expand All @@ -152,6 +154,8 @@ pip-delete-this-directory.txt
# pipenv
#Pipfile.lock
pip-log.txt
# pnpm's content-addressable store when store-dir resolves inside the repo
.pnpm-store/
# poetry
#poetry.lock
postgres-data-temp-*/
Expand Down
56 changes: 53 additions & 3 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,56 @@ Before upgrading to any new `0.x.0` version:
Entries exist only for releases that need operator action. Everything else is in the
[release notes](https://github.com/ls1intum/Hephaestus/releases).

### v0.75.0

#### 🔴 Practice area API names are replaced by practice group names

**Affected**: anything calling the application API directly. The generated Hephaestus web client is
updated in this release.

The product concept previously exposed as a *practice area* is now consistently named a **practice
group**. All `/practice-areas` routes move to `/practice-groups`; request and response fields such as
`areaSlug` and `areaName` become `groupSlug` and `groupName`; catalog collections named `areas` become `groups`. Generated schema
names likewise use `PracticeGroup` instead of `PracticeArea`. The developer-facing practice projection
moves from `/practices/learner` to `/practices/reviewed` and is named `ReviewedPractice`. The old routes
and field names are removed rather than aliased. This rename does not change which practices belong together.

**Action**: regenerate API clients and replace direct uses of the retired routes, schema names, and
fields. No operator configuration changes are required; the database migration runs automatically.

#### 🔴 The feedback reaction endpoint is replaced by a response endpoint

**Affected**: anything calling the application API directly. The Hephaestus web app is unaffected —
it never used these endpoints outside its generated client, which ships regenerated in this release.

Removed:

```
POST /workspaces/{workspaceSlug}/practices/feedback/{feedbackId}/reactions (submitReaction)
GET /workspaces/{workspaceSlug}/practices/feedback/{feedbackId}/reactions (getLatestReaction)
```

**Before**: a developer submitted an `action` (`ADDRESSED`, `DISPUTED`, or `NOT_APPLICABLE`) and an
optional `explanation`. Submissions were append-only and the GET returned the latest reaction.

**After**: the response endpoint renames `action` to `resolution` and `explanation` to `comment`. It
also accepts an independent, optional `usefulness` answer:

```
PUT /workspaces/{workspaceSlug}/practices/feedback/{feedbackId}/response
GET /workspaces/{workspaceSlug}/practices/feedback/{feedbackId}/response
DELETE /workspaces/{workspaceSlug}/practices/feedback/{feedbackId}/response
GET /workspaces/{workspaceSlug}/practices/feedback/resolution-counts
```

PUT replaces the complete response with `usefulness` (`HELPFUL` / `UNHELPFUL`), `resolution`
(`ADDRESSED` / `DISPUTED` / `NOT_APPLICABLE`), or both, plus an optional `comment` that is required
when disputing. Omitted fields are cleared. Repeating the same PUT has no effect. DELETE removes the
complete response and is safe to repeat. GET returns the response that currently stands.

**Action**: repoint any direct API caller at the new endpoint. Existing response history is preserved and
participates in current-response reads; no operator data migration is required.

### v0.74.0

#### 🔴 An agent image reference naming a channel tag is now refused
Expand Down Expand Up @@ -322,7 +372,7 @@ Update clients in the same deployment as the server and webapp. The old names ha
| `evidenceRequirements` | `automatedReviewPolicy` |
| `evidenceSupport` | `evidenceSufficiency` |
| practice `active` and `/active` | `reviewTier` and `/review-tier` (see below) |
| practice-area `active` | `visibleInPracticeDashboards` |
| practice-group `active` | `visibleInPracticeDashboards` |
| observation `artifactType` | `artifactKind` |
| observation `title` | `summary` |
| observation `reasoning` | `evidenceRationale` |
Expand Down Expand Up @@ -350,8 +400,8 @@ reviews becomes `DELIVER`, one that was not becomes `OFF`, and the migration run
and every observation is still recorded, and nothing is sent to anyone. All three values are settable
at every level; a practice only lands on `PROPOSE` because somebody put it there.

Omitting `reviewTier`, or sending it as `null`, clears the setting so the practice follows its area,
and the area follows the workspace default.
Omitting `reviewTier`, or sending it as `null`, clears the setting so the practice follows its group,
and the group follows the workspace default.

#### 🟢 A workspace can restrict review to some branches and repositories

Expand Down
4 changes: 2 additions & 2 deletions docs/admin/dsms/artifact-source-governance.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ data:
incidentalSensitiveContent: "Controls for free text"
access:
permittedRoles: [practice-review-runtime]
learnerDisclosure: "Permitted disclosure"
developerDisclosure: "Permitted disclosure"
tenantIsolation: "Enforcement and tests"
processorEgress:
permitted: true
Expand Down Expand Up @@ -198,7 +198,7 @@ automated review claim from it.
- [ ] Update the Art. 30 record and privacy notice before collection.
- [ ] Record the DPIA determination and all required approvals.
- [ ] Approve processor, region, transfer, training, and provider-retention terms.
- [ ] Define operator, learner, and evaluation audiences and propagation rules.
- [ ] Define operator, developer, and evaluation audiences and propagation rules.
- [ ] Define product, evaluation, log, cache, broker, and backup retention separately.
- [ ] Implement disconnect, purge, person erasure, expiry, export, and external-delivery handling.
- [ ] Inventory all files, mounts, caches, tools, and derivations; reject undeclared transformed views.
Expand Down
4 changes: 2 additions & 2 deletions docs/admin/dsms/dpia-prescreen.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ They remain mandatory while the determination is pending.
| Source expansion combines more contributor context than an enabled practice needs | Medium | Medium-high | Resolve the exact practice set before collection; compile a minimum evidence plan; default-deny every new source/purpose; require the [artifact-source governance gate](./artifact-source-governance.md). |
| A missing source systematically withholds feedback from particular platforms, workflows, or privacy choices | Medium | Medium | The internal readiness report records refusal separately from what a review observed. Do not compare or rank results across unequal evidence coverage. Coverage analytics and administrator remediation must not be claimed until their operator surface is implemented. |
| Repository history exposes deleted secrets or personal data beyond the reviewed change | Medium | High | Default review bundles use bounded immutable `.git`-free snapshots. Repository history is a separate governed source and is not implied by tree access. |
| Restricted or reviewer-only context is quoted into learner-facing feedback | Low-medium | High | Source-use decisions govern automated review and feedback delivery separately. Capture requires the automated-review purpose; delivery rechecks the feedback-delivery purpose, source authorization, and citation ownership. |
| Restricted or reviewer-only context is quoted into developer-facing feedback | Low-medium | High | Source-use decisions govern automated review and feedback delivery separately. Capture requires the automated-review purpose; delivery rechecks the feedback-delivery purpose, source authorization, and citation ownership. |

## 5. Safeguards that must remain in place

Expand Down Expand Up @@ -96,7 +96,7 @@ Regardless of the pending determination, a DPIA must be opened or amended before
- The processing population starts to include data subjects in a category covered by the BayLfD vulnerable-data-subjects criterion.
- Repository ingestion expands beyond administrator-selected repositories into systematic or large-scale monitoring of public sources.
- A new artifact source, source combination, private-conversation use, repository-history use, research/evaluation
reuse, retention extension, or learner/admin audience is proposed and is not already covered by the recorded
reuse, retention extension, or developer/admin audience is proposed and is not already covered by the recorded
decision.

The source-specific decision and test checklist lives in
Expand Down
2 changes: 1 addition & 1 deletion docs/admin/dsms/record-of-processing.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ The synchronised activity is analysed against a set of practices configured by t

Contributors who sign in with their GitHub or LRZ-GitLab account get a personal dashboard summarising their observations and activity, access to the conversational mentor, and their account preferences. Sign-in adds the federated user identifier, username, display name, email, and avatar URL to what Hephaestus holds about that contributor. Workspace administrators can additionally enable a leaderboard, leagues, and achievements based on workspace activity (all off by default), plus Slack integration for App Home privacy controls, mentor DMs, optional digests, and explicitly activated monitored channels.

These workspace-level configuration choices are made by the workspace administrator and TUM/AET as joint controllers under Art. 26 GDPR (the choices are enumerated in "Legal basis" below). Hephaestus is built around the contributor's own development: observations serve the contributor and give the workspace administrator a way to deliver targeted feedback during the project. Observations are advisory and contestable; the platform makes no automated decisions within the meaning of Art. 22 GDPR and feeds no grading, assessment, HR, or access-control pipeline. Signed-in contributors can stop new practice-feedback comments and related Slack reminders through the in-app **Comments and Slack reminders** setting and rate individual pieces of feedback via a helpful / not-helpful control. This delivery setting does not stop review processing; objections to processing under Art. 21 GDPR use the contact process in privacy §7.
These workspace-level configuration choices are made by the workspace administrator and TUM/AET as joint controllers under Art. 26 GDPR (the choices are enumerated in "Legal basis" below). Hephaestus is built around the contributor's own development: observations serve the contributor and give the workspace administrator a way to deliver targeted feedback during the project. Observations are advisory and contestable; the platform makes no automated decisions within the meaning of Art. 22 GDPR and feeds no grading, assessment, HR, or access-control pipeline. Signed-in contributors can stop new practice-feedback comments and related Slack reminders through the in-app **Comments and Slack reminders** setting and respond to individual pieces of feedback by recording whether they were helpful and how they were handled. This delivery setting does not stop review processing; objections to processing under Art. 21 GDPR use the contact process in privacy §7.
```

## Data subjects (Art. 30(1)(c))
Expand Down
Loading
Loading