Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .agents/skills/fix-ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ Each leg's annotation names its own command; this table is only what the annotat

| Failure | What it actually means |
|---|---|
| `routeTree.gen.ts is stale` | Only a Vite build writes it. `cd webapp && bun run build`, then commit the file. |
| `routeTree.gen.ts is stale` | A Vite build writes it. `cd webapp && bun run build`, then commit the file. |
| `README images are stale` | The storybook job runs `export:readme-assets` *after* `test:storybook`, so the job goes red having printed a clean pass line. Run `bun run --filter webapp export:readme-assets` and commit `docs/images/readme`. |
| Migrations gate | A changelog that reached `main` was edited, renamed or deleted, or a `master.xml` `<include>` was not appended at the end. Fix forward with a new changeset; never edit the released file. |
| `verify-changesets` | The PR touches shipped code with no `.changeset/*.md`. `/land-pr` step 9 has the rules. |
| `verify-changesets` | The PR touches shipped code with no `.changeset/*.md`. `/land-pr` step 7 has the rules. |
| App Server leg red on a docs-only PR | Expected, not a misconfiguration: `docs/**` is inside the `application-server` paths filter, because `docs:lint` and `check:diagrams` run on that leg. |

## 4. Reproduce locally before pushing
Expand Down
7 changes: 4 additions & 3 deletions .agents/skills/land-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ bun run db:draft-changelog # entities changed (needs Docker); then prune the
bun run db:generate-erd-docs # after any changelog change
```

`generate:api:application-server:specs` **exits 0 having written nothing** when a port it needs is
busy — HTTP, management, or the JMX port it defaults to. Pass free ports; the exact invocation is in
`server/AGENTS.md` § OpenAPI generation exits 0 having written nothing.
`generate:api:application-server:specs` **fails when a port it needs is busy** — HTTP, management, or
the JMX port it defaults to. It restores the previous spec rather than committing an empty one, so
the cost is a wasted Maven cycle. Pass free ports; the exact invocation is in `server/AGENTS.md`
§ OpenAPI generation ports.

## 5. Run the tests your diff can break

Expand Down
5 changes: 5 additions & 0 deletions .changeset/calm-mentors-welcome.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hephaestus": patch
---

The landing and about pages now say plainly what Hephaestus is, show the kind of gap it points out, name the practice groups a workspace can turn on, and credit Applied Education Technologies at TUM.
2 changes: 1 addition & 1 deletion .changeset/calm-practices-expand.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ while paused is never released by resuming. Proposals that nobody has decided re
administrator to approve or reject after sending resumes.

When a review needs approval, the approval page now shows the exact summary and every inline comment
as one package. One decision releases or rejects the whole review; automatically authorized findings
as one package. One decision releases or rejects the whole review; automatically authorized observations
in the same review wait for that decision instead of appearing early. After approval, the delivery
page shows how many comments have reached the provider while safe retries finish the remainder.

Expand Down
2 changes: 1 addition & 1 deletion .changeset/compose-feedback-for-real-reviews.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"hephaestus": minor
---

Practice reviews deliver feedback again. A review measured a pull request, recorded what it found, and then stopped: the step that turns those findings into something a developer reads was never switched on, so every review ended with its results stored and nothing said. Reviews now compose feedback for each lane the occasion can reach — the note on the work, the developer's own practice pages, and an ongoing conversation — and issue reviews compose for the two longitudinal lanes, since an issue is not the work a note belongs on.
Practice reviews deliver feedback again. A review measured a pull request, recorded what it found, and then stopped: the step that turns those observations into something a developer reads was never switched on, so every review ended with its results stored and nothing said. Reviews now compose feedback for each lane the occasion can reach — the note on the work, the developer's own practice pages, and an ongoing conversation — and issue reviews compose for the two longitudinal lanes, since an issue is not the work a note belongs on.

**Operators:** feedback now appears where it previously did not, so a workspace with review switched on begins posting again. Nothing new is required of you, and the instance-wide Silent Mode brake still holds everything back while it is engaged — but if you upgraded during the window where reviews were silent, this is the change that ends it.
2 changes: 1 addition & 1 deletion .changeset/evidence-boundary-withholds-the-claim.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"hephaestus": patch
---

A review whose evidence check fails on one observation now delivers the others. The check that refuses to show a developer a claim it cannot trace back to the code applied to the whole review at once: one practice that mis-quoted its source — by a stray character, in a file the reader never sees — withheld every other finding in that review, including correct, fully evidenced ones. The developer saw nothing at all. Only a quote that does not match its source is treated this way; a citation to evidence the review never gathered still stops the whole delivery, as before. What was withheld is logged with the reason, and a review in which no claim can be verified still fails rather than arriving empty.
A review whose evidence check fails on one observation now delivers the others. The check that refuses to show a developer a claim it cannot trace back to the code applied to the whole review at once: one practice that mis-quoted its source — by a stray character, in a file the reader never sees — withheld every other observation in that review, including correct, fully evidenced ones. The developer saw nothing at all. Only a quote that does not match its source is treated this way; a citation to evidence the review never gathered still stops the whole delivery, as before. What was withheld is logged with the reason, and a review in which no claim can be verified still fails rather than arriving empty.
2 changes: 1 addition & 1 deletion .changeset/oxlint-replaces-biomes-linter.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Also fixed, all surfaced by a stricter type and lint gate across the whole codeb

- A review schedule saved with a time that had no minutes (`9` rather than `09:00`) stored no minute
at all instead of falling back to the hour's start.
- Audit-log entries and the curated-catalogue version panel printed `[object Object]` for any field
- Audit-log entries and the instance catalog version panel printed `[object Object]` for any field
whose value was not plain text.
- A cookie-consent choice was read back from browser storage without checking it, so a corrupted
entry could be treated as a decision.
Expand Down
2 changes: 1 addition & 1 deletion .changeset/reviews-lead-with-what-matters.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"hephaestus": patch
---

A review comment now leads with its most serious finding and the one edit that fixes it, instead of leading with whichever finding happened to have no line number attached. Each finding says what to do before it says why it matters, and the reasoning is one sentence rather than the same paragraph on every review that touches the practice.
A review comment now leads with its most serious point and the one edit that fixes it, instead of leading with whichever one happened to have no line number attached. Each point says what to do before it says why it matters, and the reasoning is one sentence rather than the same paragraph on every review that touches the practice.
2 changes: 1 addition & 1 deletion .changeset/reviews-open-in-their-own-words.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"hephaestus": patch
---

A review comment now opens with a sentence written about your change, instead of one of a handful of fixed lines that read the same on every review — including on reviews that opened with praise ahead of a serious problem. When the review has nothing worth opening on, it opens on its first finding.
A review comment now opens with a sentence written about your change, instead of one of a handful of fixed lines that read the same on every review — including on reviews that opened with praise ahead of a serious problem. When the review has nothing worth opening on, it opens on its first observation.
2 changes: 1 addition & 1 deletion .changeset/version-banner-sits-inside-the-panel.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
"hephaestus": patch
---

Fixes the "Uses Hephaestus default" notice in the instance practice catalogue running edge to edge while every field below it was indented. It now sits inside the panel like the rest of the content, and scrolls with it instead of holding a fixed strip at the top.
Fixes the "Uses Hephaestus default" notice in the instance practice catalog running edge to edge while every field below it was indented. It now sits inside the panel like the rest of the content, and scrolls with it instead of holding a fixed strip at the top.
4 changes: 2 additions & 2 deletions .claude/skills/fix-ci/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ Each leg's annotation names its own command; this table is only what the annotat

| Failure | What it actually means |
|---|---|
| `routeTree.gen.ts is stale` | Only a Vite build writes it. `cd webapp && bun run build`, then commit the file. |
| `routeTree.gen.ts is stale` | A Vite build writes it. `cd webapp && bun run build`, then commit the file. |
| `README images are stale` | The storybook job runs `export:readme-assets` *after* `test:storybook`, so the job goes red having printed a clean pass line. Run `bun run --filter webapp export:readme-assets` and commit `docs/images/readme`. |
| Migrations gate | A changelog that reached `main` was edited, renamed or deleted, or a `master.xml` `<include>` was not appended at the end. Fix forward with a new changeset; never edit the released file. |
| `verify-changesets` | The PR touches shipped code with no `.changeset/*.md`. `/land-pr` step 9 has the rules. |
| `verify-changesets` | The PR touches shipped code with no `.changeset/*.md`. `/land-pr` step 7 has the rules. |
| App Server leg red on a docs-only PR | Expected, not a misconfiguration: `docs/**` is inside the `application-server` paths filter, because `docs:lint` and `check:diagrams` run on that leg. |

## 4. Reproduce locally before pushing
Expand Down
7 changes: 4 additions & 3 deletions .claude/skills/land-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ bun run db:draft-changelog # entities changed (needs Docker); then prune the
bun run db:generate-erd-docs # after any changelog change
```

`generate:api:application-server:specs` **exits 0 having written nothing** when a port it needs is
busy — HTTP, management, or the JMX port it defaults to. Pass free ports; the exact invocation is in
`server/AGENTS.md` § OpenAPI generation exits 0 having written nothing.
`generate:api:application-server:specs` **fails when a port it needs is busy** — HTTP, management, or
the JMX port it defaults to. It restores the previous spec rather than committing an empty one, so
the cost is a wasted Maven cycle. Pass free ports; the exact invocation is in `server/AGENTS.md`
§ OpenAPI generation ports.

## 5. Run the tests your diff can break

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/ci-quality-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ jobs:
COMPONENTS_OK=true
STORIES_OK=true
SORT_OK=true
TOKENS_OK=true
BUILD_OK=true
ROUTES_OK=true
TESTS_OK=true
Expand All @@ -179,6 +180,7 @@ jobs:
bun ../scripts/check-presentational-components.ts || { COMPONENTS_OK=false; ISSUES_FOUND+=("Components must take data as props. Run: bun run check:components"); }
bun ../scripts/check-story-prose.ts || { STORIES_OK=false; ISSUES_FOUND+=("Story prose renders HTML paragraphs. Run: bun run check:stories"); }
bun ../scripts/check-story-sort.ts || { SORT_OK=false; ISSUES_FOUND+=("Storybook sidebar order is stale. Run: bun run check:story-sort"); }
bun ../scripts/check-docs-tokens.ts && bun test ../scripts/check-docs-tokens.test.ts || { TOKENS_OK=false; ISSUES_FOUND+=("The docs site copies a web app colour that has since changed. Run: bun run check:docs-tokens"); }
timeout --kill-after=30s 10m bun run test \
|| { TESTS_OK=false; ISSUES_FOUND+=("Unit tests failed. Run: cd webapp && bun run test"); }

Expand All @@ -198,6 +200,7 @@ jobs:
[[ "$COMPONENTS_OK" == "false" ]] && echo "| Presentational components | :x: Failed | \`bun run check:components\` |" >> $GITHUB_STEP_SUMMARY
[[ "$STORIES_OK" == "false" ]] && echo "| Story prose | :x: Failed | \`bun run check:stories\` |" >> $GITHUB_STEP_SUMMARY
[[ "$SORT_OK" == "false" ]] && echo "| Storybook sidebar order | :x: Failed | \`bun run check:story-sort\` |" >> $GITHUB_STEP_SUMMARY
[[ "$TOKENS_OK" == "false" ]] && echo "| Docs colour tokens | :x: Failed | \`bun run check:docs-tokens\` |" >> $GITHUB_STEP_SUMMARY
[[ "$BUILD_OK" == "false" ]] && echo "| Vite build | :x: Failed | \`cd webapp && bun run build\` |" >> $GITHUB_STEP_SUMMARY
[[ "$ROUTES_OK" == "false" ]] && echo "| routeTree.gen.ts up to date | :x: Stale | \`cd webapp && bun run build\` and commit |" >> $GITHUB_STEP_SUMMARY
[[ "$TESTS_OK" == "false" ]] && echo "| Unit tests | :x: Failed | \`cd webapp && bun run test\` |" >> $GITHUB_STEP_SUMMARY
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ jobs:
timeout --kill-after=30s 15m bun run test:storybook
bun run export:readme-assets
if [[ -n "$(git status --porcelain --untracked-files=all -- ../docs/images/readme)" ]]; then
echo "::error::README images are stale. Run 'bun run --filter webapp export:readme-assets' and commit the result."
echo "::error::README or documentation images are stale. Run 'bun run --filter webapp export:readme-assets' and commit the result."
git status --short --untracked-files=all -- ../docs/images/readme
exit 1
fi
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/cicd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
webapp:
- 'webapp/**'
- 'docs/images/readme/**'
# check:docs-tokens compares this stylesheet with webapp/src/styles.css, so both
# halves of that pair have to reach the leg that runs it.
- 'docs/src/css/custom.css'
- '.oxlintrc.json'
- '.oxfmtrc.json'
# check:components, check:stories and check:story-sort live here, run on the Webapp leg.
Expand Down
20 changes: 13 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

**⚠️ Do NOT stage, commit, or push unless you have permission to do so.**

Hephaestus reviews software practices for engineering teams: it ingests work from GitHub, GitLab,
Slack and Outline, has an LLM agent observe it against a curated practice catalogue, and delivers
feedback to the developer in-context, in a reflection page, or in conversation.
Hephaestus is an open-source AI mentor for software teams. It reads the work developers already do
in GitHub, GitLab, Slack and Outline against the engineering practices their project cares about — a
curated set of practices ships with it — and delivers practice feedback on the work itself, on the developer's
own practice pages, or in conversation.

`docs/contributor/practice-feedback-language.md` is the normative vocabulary and it binds this file
too: the unit a review records is an **observation**, the unit a developer receives is **feedback**,
and neither the application nor a review is an *agent*.

- `server/` — Spring Boot 4 + Java 21 + Spring Modulith 2. Liquibase-managed PostgreSQL, SQL-layer
multi-tenancy (`core/tenancy/`), generated `openapi.yaml`. Three runtime roles (`server`, `worker`,
Expand Down Expand Up @@ -189,10 +194,11 @@ as a Liquibase `<changeSet>` — a schema change needs both. Full flow:

Each of these fails *quietly* — the command reports success and leaves you with a stale or wrong result.

- **`generate:api:application-server:specs` exits 0 when the app never started.** It boots the server
to scrape springdoc, so a busy HTTP, management **or JMX** port means no spec is written and the exit
code is still 0 — you commit a spec missing your new endpoint. Pass free ports; the full recipe and
the default port numbers are in `server/AGENTS.md`.
- **`generate:api:application-server:specs` needs three free ports.** It boots the server to scrape
springdoc, so a busy HTTP, management **or JMX** port fails the run. It fails loudly and restores
the previous spec rather than committing an empty one — `scripts/generate-openapi-spec.ts` — so the
cost is a wasted Maven cycle, not a wrong spec. The recipe and the default port numbers are in
`server/AGENTS.md` § OpenAPI generation ports.
- **That script runs a full Maven `verify`.** On a cold cache the first run downloads the whole Spring
Boot dependency tree; expect several minutes.
- **`db:draft-changelog` needs Docker on PATH** and a running daemon.
Expand Down
6 changes: 3 additions & 3 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ missing, follow [Who counts as a person](https://ls1intum.github.io/Hephaestus/a
role-inconsistent required setting.

Production processes now validate the applicable requirements in the configuration readiness
catalogue together and refuse to start until every reported error is resolved. The failure report
catalog together and refuse to start until every reported error is resolved. The failure report
identifies properties and documentation but never includes configured values.

**Action**: before upgrading, compare every production role's settings with the
Expand Down Expand Up @@ -368,8 +368,8 @@ record whose conduct it judged, so their observations were filed against the aut
rather than the reviewer who wrote the comments. An occasion now records it, and a review that cannot
name the reviewer does not run.

A workspace installs the shipped catalogue once, so an existing workspace still holds the old wording.
Open **Practice catalogue** and apply the update to those three practices to pick it up. Until you do,
A workspace installs the shipped catalog once, so an existing workspace still holds the old wording.
Open **Practice catalog** and apply the update to those three practices to pick it up. Until you do,
they behave exactly as they did before — nothing new is recorded against the wrong person, because the
new guard reads the occasion and the old wording still says *author*.

Expand Down
Loading
Loading