The note predated 7bda56d and f574884, so two of its three points were
already shipped when it was picked up. Records what each commit actually
closed, and that the .env deny rules block the two committed template
files that hold no secrets.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No phase work in flight: Phase 15 (8/8) and Phase 16 (5/5) are both closed and
the roadmap reflects it. The handoff therefore sits at project level rather
than in a phase directory.
Records four anti-patterns discovered through actual failure this session, two
of them marked blocking: the tautological test that let the objectGUID defect
through review, and the fact that /opt/tessera is not a checkout, so compose
changes in this repository never reach the test server.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The page carries platform config, tenant config and one per-user setting. The
per-user one -- the digest interval, which is what an ordinary user actually
comes for -- sits last, below three blocks they may not change.
Checked before writing it up: this is not a permission hole. The admin
endpoints are @Roles-guarded server side, so a normal user cannot change
anything; the page simply has no role check of its own, so they see controls
that fail on save.
The second half is a product question deliberately left open, because it is
not specific to this module: DKV-Fleet has the same shape, and every future
module with a personal setting will ask it again.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
/opt/tessera is not a working copy -- the compose file there is maintained by
hand, and the deploy path only pulls images. Two consequences showed up on the
same day: the renamed encryption key never reached the container although it
was in the server .env, and the "refuse to start without a key" guard does not
apply on alpha at all, because it only exists in the repository file.
The item deliberately stops short of proposing a fix to apply: it first asks
why the file is hand-maintained, since it may carry host-specific settings the
repository lacks, and moving to a checkout blindly would break the running
system.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fallout from encrypting the LDAP bind password: the base compose file still
carries a hardcoded fallback key, so an install that never sets the variable
starts anyway and encrypts everything with a value that is in the repository.
The prod compose already requires it, which is the behaviour the base file
should have too.
Whether the example env files explain the key could not be checked in that
session, so the item says to look first rather than asserting it is missing.
Also notes, as an optional follow-up, why the variable is called
CALENDAR_ENCRYPTION_KEY and what a rename would have to handle.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Notes what was deliberately left out: extracting and renaming the crypto
service out of calendar/ touches five modules and belongs in its own change,
so the existing provider is reused as-is and the naming smell is recorded in
LdapModule instead.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The AD group membership sync shipped on 2026-08-04 as 614de28; only its
summary was never written, which left Phase 15 sitting at 7/8 as if work were
outstanding. Nothing was.
Each promise the plan made is checked against today's source rather than
against the commit message: bound-only selection, no second sync job, deletion
restricted to source LDAP, manual memberships preserved, memberOf reverse query
instead of attribute reads, RFC-4515 escaping of the group DN, no nested-group
resolution, order independence, per-group error isolation. The 2026-08-11 sync
run on alpha additionally exercised this path against a real directory.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Records the user's choice between the two candidate link targets (the notice
page on oeffentlichevergabe.de, not the awarding portal's own page), what was
checked before touching the adapter, and the trap in verifying it: the target
is a single-page app that answers 200 with an identical shell for any id, so
only rendered content proves the link works.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The user released the full run once it was clear nothing there is productive
yet. All three report lines appeared (401 created / 9 memberships added / 0
groups adopted, renamed or deleted), and the amber default-marker line stayed
absent as it should when nothing was deleted.
The run doubles as the end-to-end proof for the 260811-f9i fix: the imported
group survived the sweep with its memberships filled, where the old filter
would have deleted it in exactly this run.
Roadmap marks Phase 16 complete; Phase 15 keeps its 7/8 with the reason named.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Neither is a Phase 16 defect; both surfaced while testing it and would
otherwise have been lost with the session.
1. Module activation has no licence check — a tenant admin can activate any
catalogue module for their own tenant. The grants matrix is NOT the hole: it
only distributes what is already active. Carries open product questions
(who issues licences, what expiry does), so it is written up as a draft, not
a decision.
2. The LDAP bind password is stored in clear text although an AES-256-GCM
service already exists and is used for calendar, DKV and tender inbox
credentials. Hashing is not an option here — the password must be replayable
to bind against the directory — so encryption at rest is the fix. No open
questions, just work.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The user has no write access to the company AD, so tests 1, 3, 4 and 8 cannot
be run there, and building a throwaway domain controller for them was judged
disproportionate now that the one substantive defect at this spot is found and
fixed (UAT test 2 -> quick task 260811-f9i).
Recorded rather than hidden: A1 (objectGUID survives a rename) now rests on
Microsoft's documentation, not on our own measurement. The Tessera-side rename
and delete logic stays covered by unit tests against fixtures. If a rename ever
fails to propagate in production, 16-VERIFICATION.md names that as the starting
point.
Phase 16 marked complete in STATE.md.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Quick task 260811-f9i: plan and summary of the fix, STATE.md row, and the UAT
test 2 result. Test 2 was the read-only A2 check against the real directory --
it turned assumption A2 from "unverified" into "false as implemented" and
surfaced a defect that would have deleted every AD-bound group on the first
real sync.
Also records why the defect survived review: the spec mocks built their
expected filter with the same escape helper the production code used, so the
test asserted self-consistency rather than directory behaviour.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ran the Phase 16 browser walkthrough against alpha.tessera.ctl.de with the
real AD (balios.ctl.local) behind it.
- Test 5 (AD group import section): passed. 236 discovered entries, none of
them OUs; selection count, disabled-at-zero button, already-imported badge,
result block and the discovery error state all behave as specified.
- Test 6 (group dialog, three states): passed. Includes the WR-02 case — a
409 name collision stays visible in the dialog with the input preserved.
- Test 7: partial. Error path of the sync report and the grants-matrix column
search under both internal and AD name pass; the number rows of a successful
sync run are still open because a real sync was skipped by request (no
group/OU filter set, so it would import every person under DC=ctl,DC=local).
Tests 1-4 and 8 remain open — they need AD write access or are backstop
assertions. CN=Claude_VT stays imported on alpha because tests 3 and 4 need it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Marks all four Warning findings from 16-REVIEW.md as resolved with their
fix commit hashes; the two Info findings (IN-01/IN-02) remain open and
out of scope for this fix pass. Appends a note to 16-03-SUMMARY.md
recording the WR-02/WR-03/WR-04 behavior change in
syncBoundGroupsForTenant(), since that summary still described the
pre-fix behavior.
- 16-05-SUMMARY.md documents the two-task plan (sync-report wiring,
grants-matrix internal-name fallback).
- PERM-02 marked complete in REQUIREMENTS.md: all five Phase-16 success
criteria are code-complete across plans 16-01..16-03; this plan
delivered the last missing visibility layer (D-05/D-06) and the
third D-04 display site.
- WINDOWS.md #6: this plan's own manual browser walkthrough (sync
report three-line render, amber default-marker line, grants-matrix
two-name search) not executed — no browser tool in this session.
Documents the GroupFormModal three-state rebuild (D-03/D-04/D-07), the
groups-list internalName fallback, and the ldapBind i18n cleanup for
Phase 16 Plan 4.