diff --git a/docs/architecture/dal-domain-alignment.md b/docs/architecture/dal-domain-alignment.md
new file mode 100644
index 0000000..1261cc9
--- /dev/null
+++ b/docs/architecture/dal-domain-alignment.md
@@ -0,0 +1,13 @@
+# Thalos DAL Domain Alignment
+
+## Goal
+Align DAL with thalos-domain abstractions while keeping DAL technical.
+
+## DAL Responsibilities
+- Identity persistence and retrieval
+- Technical data translation
+- Provider/repository boundaries
+
+## Prohibited
+- Identity policy decision ownership
+- Service orchestration concerns
diff --git a/docs/migration/dal-port-alignment-map.md b/docs/migration/dal-port-alignment-map.md
new file mode 100644
index 0000000..dbbc0be
--- /dev/null
+++ b/docs/migration/dal-port-alignment-map.md
@@ -0,0 +1,6 @@
+# Thalos DAL Port Alignment Map
+
+## Alignment Areas
+- DAL read/write ports map to domain contracts.
+- Technical DTO translation remains in DAL adapters.
+- Domain policy semantics are not reimplemented in DAL.
diff --git a/docs/migration/technical-mapping-rules.md b/docs/migration/technical-mapping-rules.md
new file mode 100644
index 0000000..98161ed
--- /dev/null
+++ b/docs/migration/technical-mapping-rules.md
@@ -0,0 +1,6 @@
+# Thalos DAL Technical Mapping Rules
+
+## Rules
+- Mapping logic remains technical and deterministic.
+- No policy evaluation branching in DAL mapping layer.
+- Correlation and metadata pass-through remains unchanged.
diff --git a/src/Thalos.DAL/Contracts/IdentityUserLookupRequest.cs b/src/Thalos.DAL/Contracts/IdentityUserLookupRequest.cs
index 8e6d4e4..9c5117f 100644
--- a/src/Thalos.DAL/Contracts/IdentityUserLookupRequest.cs
+++ b/src/Thalos.DAL/Contracts/IdentityUserLookupRequest.cs
@@ -5,4 +5,5 @@ namespace Thalos.DAL.Contracts;
///
/// Contract envelope metadata.
/// Identity subject identifier.
-public sealed record IdentityUserLookupRequest(IdentityContractEnvelope Envelope, string SubjectId);
+/// Tenant identifier.
+public sealed record IdentityUserLookupRequest(IdentityContractEnvelope Envelope, string SubjectId, string TenantId);
diff --git a/src/Thalos.DAL/Contracts/IdentityUserRecord.cs b/src/Thalos.DAL/Contracts/IdentityUserRecord.cs
index aa364ac..095f3c5 100644
--- a/src/Thalos.DAL/Contracts/IdentityUserRecord.cs
+++ b/src/Thalos.DAL/Contracts/IdentityUserRecord.cs
@@ -7,8 +7,14 @@ namespace Thalos.DAL.Contracts;
/// Identity subject identifier.
/// Tenant scope identifier.
/// Current user status.
+/// Persisted token projection for subject/tenant.
+/// Persisted token expiration in seconds.
+/// Persisted policy context projection.
public sealed record IdentityUserRecord(
IdentityContractEnvelope Envelope,
string SubjectId,
string TenantId,
- string Status);
+ string Status,
+ string Token,
+ int ExpiresInSeconds,
+ bool ContextSatisfied);
diff --git a/src/Thalos.DAL/Providers/InMemory/InMemoryUserDataProvider.cs b/src/Thalos.DAL/Providers/InMemory/InMemoryUserDataProvider.cs
index 4d54c23..66cd15d 100644
--- a/src/Thalos.DAL/Providers/InMemory/InMemoryUserDataProvider.cs
+++ b/src/Thalos.DAL/Providers/InMemory/InMemoryUserDataProvider.cs
@@ -20,8 +20,11 @@ public sealed class InMemoryUserDataProvider : IUserDataProvider
var record = new IdentityUserRecord(
request.Envelope,
request.SubjectId,
- "tenant-default",
- "active");
+ request.TenantId,
+ "active",
+ $"{request.SubjectId}:{request.TenantId}:token",
+ 1800,
+ true);
return Task.FromResult(record);
}
diff --git a/src/Thalos.DAL/Repositories/IdentityRepository.cs b/src/Thalos.DAL/Repositories/IdentityRepository.cs
index 8725a0d..bbe768c 100644
--- a/src/Thalos.DAL/Repositories/IdentityRepository.cs
+++ b/src/Thalos.DAL/Repositories/IdentityRepository.cs
@@ -15,15 +15,19 @@ public sealed class IdentityRepository(
IdentityTokenLookupRequest request,
CancellationToken cancellationToken = default)
{
- var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId);
+ var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId, request.TenantId);
var userRecord = await userDataProvider.ReadUserAsync(userRequest, cancellationToken);
if (userRecord is null)
{
return null;
}
- var token = $"{request.SubjectId}:{request.TenantId}:token";
- return new IdentityTokenRecord(request.Envelope, request.SubjectId, request.TenantId, token, 1800);
+ return new IdentityTokenRecord(
+ request.Envelope,
+ request.SubjectId,
+ request.TenantId,
+ userRecord.Token,
+ userRecord.ExpiresInSeconds);
}
///
@@ -31,15 +35,18 @@ public sealed class IdentityRepository(
IdentityPolicyLookupRequest request,
CancellationToken cancellationToken = default)
{
- var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId);
+ var userRequest = new IdentityUserLookupRequest(request.Envelope, request.SubjectId, request.TenantId);
var userRecord = await userDataProvider.ReadUserAsync(userRequest, cancellationToken);
if (userRecord is null)
{
return null;
}
- var contextSatisfied = string.Equals(userRecord.Status, "active", StringComparison.OrdinalIgnoreCase);
- return new IdentityPolicyRecord(request.Envelope, request.SubjectId, request.PermissionCode, contextSatisfied);
+ return new IdentityPolicyRecord(
+ request.Envelope,
+ request.SubjectId,
+ request.PermissionCode,
+ userRecord.ContextSatisfied);
}
///