{ "version": "1.0", "timestamp": "2026-07-14T08:16:00.000Z", "phase": null, "phase_name": null, "phase_dir": null, "plan": null, "task": null, "total_tasks": null, "status": "idle", "completed_tasks": [ {"id": 1, "name": "LDAP: fix FavoriteLink 500 (missing migration, prod)", "status": "done", "commit": "afef9b2"}, {"id": 2, "name": "LDAP: revert CTL-specific AD prefill per user feedback", "status": "done", "commit": "8e8305c"}, {"id": 3, "name": "LDAP: allow testing connection before saving config", "status": "done", "commit": "39aa4bf"}, {"id": 4, "name": "LDAP: support anonymous bind (optional bindDn/bindPassword)", "status": "done", "commit": "010aceb"}, {"id": 5, "name": "Auth: case-insensitive usernames (login, seed, LDAP sync, migration)", "status": "done", "commit": "baff7ce"}, {"id": 6, "name": "LDAP: fix ldapts empty-array-attribute bug causing email collision on sync", "status": "done", "commit": "246dc89"}, {"id": 7, "name": "LDAP: search box for discovered groups/OUs list", "status": "done", "commit": "aaa2922"}, {"id": 8, "name": "Favorites: icon proxy for CORP-restricted sites (claude.ai) + realistic UA fix", "status": "done", "commit": "f06a2ff (and related)"}, {"id": 9, "name": "LDAP: per-user exclude/denylist filter -- exclude individual usernames (service accounts like administrator/krbtgt/guest/dns-ldap/ldap$) from sync, independent of the group/OU include-filter. Backend (schema+migration, DTO, service skip-before-syncedDns so excluded users get deactivated, controller+scheduler threading), frontend admin section (add/remove/save), de/en i18n, 3 unit tests. Live-verified on alpha.tessera.ctl.de.", "status": "done", "commit": "9d1323f"}, {"id": 10, "name": "Live full-sync verification against real Zentyal AD -- ran 'Jetzt synchronisieren' with exclude list saved; result Erstellt:0/aktualisiert:2/deaktiviert:4; DB confirmed the 4 excluded service accounts isActive=false, 2 real LDAP users active, 0 wrongly created", "status": "done", "commit": "9d1323f (verification)"}, {"id": 11, "name": "STATE.md quick-tasks table catch-up -- added rows for the direct-fix commits (8e8305c, 39aa4bf, 010aceb, baff7ce, 246dc89, aaa2922, 9d1323f) that had no /gsd-quick dirs", "status": "done", "commit": "(STATE.md edit)"} ], "remaining_tasks": [], "blockers": [], "async_jobs": [], "human_actions_pending": [], "decisions": [ {"decision": "Reverted CTL-specific AD server/domain hardcoded as form defaults", "rationale": "User: 'das war nie das Ziel' -- Tessera is a generic multi-tenant product, must not bake one customer's infra into shared admin UI", "phase": null}, {"decision": "LDAP bindDn/bindPassword made fully optional (anonymous bind support)", "rationale": "User explicitly requested removing the requirement to enter a bind user/password", "phase": null}, {"decision": "Usernames normalized to lowercase everywhere (storage + lookup), not just at login", "rationale": "User: login was case-sensitive and shouldn't be; centralized in UserService rather than per-callsite", "phase": null}, {"decision": "Per-user exclude list skips matches BEFORE recording the DN in syncedDns", "rationale": "So a user added to the denylist after already being imported gets deactivated on the next sync (rather than lingering active); exclude match is case-insensitive to align with lowercase username handling", "phase": null} ], "uncommitted_files": ["(unstaged) .planning/STATE.md, .planning/HANDOFF.json, .planning/.continue-here.md -- planning bookkeeping, not yet committed"], "next_action": "No open LDAP work. All three previously-remaining items (per-user exclude filter, live full-sync verify, STATE.md catch-up) are done. Next session: ask the user what to pick up next -- likely new module work now that v1.0 + LDAP hardening are complete. No GSD phase active.", "context_notes": "This whole session was reactive, ad-hoc fixing driven by live-testing on a real production-style deployment (alpha.tessera.ctl.de, test box 192.168.13.12) plus a freshly stood-up Zentyal/Samba AD test directory (192.168.13.13, domain intern.vicolab.de) that the user built specifically so LDAP could be tested against something real. No GSD phase is active -- the v1.0 milestone was already at 100% before this session; everything today was quick-task-style bugfixing/feature work, several done directly without spinning up the full /gsd-quick planner+executor pipeline (justified each time by being small, fully-diagnosed, and urgent to unblock live testing). CRITICAL boundary: user explicitly does NOT want me running docker compose pull/up/down/restart/rebuild on the test server myself -- only docker logs / psql for read-only debugging. They pull/rebuild themselves and tell me when done, then I test via Playwright in the browser." }