Werkzeugkasten: Zugangsdaten je Einheit (#692)
A unit holds credentials for its members, by tool and setting - needed once,
not once per agent, and other units never get them.
- UnitConfig.credentials, protected by ConfigSecrets like every secret.
- OrgChart.ToolSettingsFor: an agent's own settings, completed by the nearest
unit up that holds the value; own non-empty values win; no tool is granted.
Used for runs, tool jobs and preflight probes.
- OrgAdministration.SetUnitCredential, PUT /organisation/units/{id}/credentials;
the view lists held settings, never values.
- Templates never carry unit credentials; they are named instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
661807b2d0
commit
9a265888f8
@@ -24,7 +24,9 @@ public sealed record UnitDto(
|
||||
// #693: the lead's spot checks; null: none.
|
||||
UnitInspectionDto? Inspection = null,
|
||||
// #702: what the unit puts to a blind vote; null: nothing.
|
||||
UnitVotesDto? Votes = null);
|
||||
UnitVotesDto? Votes = null,
|
||||
// #692: the credentials the unit holds, by tool — names only, never values.
|
||||
IReadOnlyDictionary<string, IReadOnlyList<string>>? CredentialKeys = null);
|
||||
|
||||
/// <summary>#698: One version of a unit's doctrine.</summary>
|
||||
public sealed record DoctrineDto(int Version, string Text, string SetBy, DateTime SetAt, string? RunId, string Reason);
|
||||
@@ -42,6 +44,9 @@ public sealed record InspectionInputDto(bool Enabled, double? Rate, double? Dens
|
||||
|
||||
public sealed record FindingDto(string Kind, string Text);
|
||||
|
||||
/// <summary>#692: One credential a unit holds; an empty value removes it.</summary>
|
||||
public sealed record UnitCredentialInputDto(string Tool, string Key, string? Value, string Reason = "");
|
||||
|
||||
/// <summary>#691: A template to preview or import, with what the human changes on the way in.</summary>
|
||||
public sealed record TemplateImportDto(
|
||||
System.Text.Json.JsonElement Template,
|
||||
|
||||
@@ -30,7 +30,10 @@ internal static class OrganisationEndpoints
|
||||
chart.PathOf(u.Id), chart.Depth(u.Id),
|
||||
u.Approvals is { } ap ? new UnitApprovalsDto(ap.Operations, ap.PerDay, ap.Hours) : null,
|
||||
u.Inspection is { } ins ? new UnitInspectionDto(ins.Rate, ins.DenseRate, ins.NewDays, ins.PerDay) : null,
|
||||
u.Votes is { } v ? new UnitVotesDto(v.Operations, v.Voters, v.ApproveAt, v.RejectAt, v.EffectiveQuorum, v.Hours, v.PerDay) : null))
|
||||
u.Votes is { } v ? new UnitVotesDto(v.Operations, v.Voters, v.ApproveAt, v.RejectAt, v.EffectiveQuorum, v.Hours, v.PerDay) : null,
|
||||
u.Credentials is { Count: > 0 } held
|
||||
? held.ToDictionary(h => h.Key, h => (IReadOnlyList<string>)h.Value.Keys.Order(StringComparer.OrdinalIgnoreCase).ToList())
|
||||
: null))
|
||||
.ToList();
|
||||
|
||||
var agents = host.Instance.Agents
|
||||
@@ -105,6 +108,10 @@ internal static class OrganisationEndpoints
|
||||
return Results.Ok(new OutcomeDto(true, set.IsEmpty ? $"Doctrine of '{unit.Name}' removed." : $"Doctrine of '{unit.Name}' set (version {set.Version})."));
|
||||
});
|
||||
|
||||
// #692: Credentials a unit holds for its members — written here, never read back.
|
||||
org.MapPut("/units/{unitId}/credentials", (AppHost host, string unitId, UnitCredentialInputDto input) =>
|
||||
host.Organisation.SetUnitCredential(unitId, input.Tool, input.Key, input.Value, input.Reason).ToResponse());
|
||||
|
||||
// #691: The organisation as a template file — exported without credentials, imported only after a preview and a confirmation.
|
||||
org.MapGet("/template", (AppHost host, string? name, string? description) =>
|
||||
Results.Text(System.Text.Json.JsonSerializer.Serialize(
|
||||
|
||||
Reference in New Issue
Block a user