package com.correx.core.approvals

import com.correx.core.events.types.ProjectId
import com.correx.core.events.types.SessionId
import java.nio.file.Paths

/**
 * Reserved event-store stream that holds cross-session approval grants (PROJECT and GLOBAL scopes).
 *
 * Session-scoped grants live in their own session's stream and die with it; project/global grants
 * must outlive any single session and be visible to every other one, so they are appended here
 * instead. The approval gate folds this ledger ([com.correx.core.approvals.DefaultApprovalReducer]
 * over [DefaultApprovalRepository.getApprovalState]) and unions its grants with the running
 * session's own before evaluating — see `SessionOrchestrator`. Revocation appends an
 * [com.correx.core.events.events.ApprovalGrantExpiredEvent] to the same stream, which the reducer
 * drops, so the audit trail stays intact (invariant #9: record facts, replay reads them).
 *
 * The id is a sentinel, not a real session; it never carries a workflow run.
 */
val GRANT_LEDGER_SESSION_ID = SessionId("__grant_ledger__")

/**
 * Derives a stable [ProjectId] from a workspace root path so PROJECT-scoped grants created in one
 * session match later sessions opened on the same repository. Both the grant-creation site (server)
 * and the approval gate (orchestrator) run in the same process, so canonicalising to a normalised
 * absolute path yields the same id on both sides regardless of how the root was spelled.
 */
object ProjectIdentity {
    fun of(workspaceRoot: String): ProjectId =
        ProjectId(Paths.get(workspaceRoot).toAbsolutePath().normalize().toString())
}
