RoleConfig.confirm_policy was parsed but never acted on. Wire the three
strategies for how OTHERS' action requests are confirmed (the owner's own
requests always auto-run regardless):
- manual (default): ask the owner every time
- auto: run without asking — full trust — still fully audited
- remember: ask once per action verb, then reuse that decision (approve →
auto-run same verb; reject → auto-decline same verb)
- gateDecision(requester, verb) returns auto / ask / reject
- ApprovalRequest.Verb carries the action verb (remember key + audit)
- handleOwnerDecision caches the decision per verb under the remember policy
- applyRoleConfig fills opts.ConfirmPolicy; launchConnector wires + logs it
Tests: auto runs without asking, manual asks, remember reuses the 1st decision.
RoleConfig.allowed_scopes was parsed but never enforced. Now an action whose
product is outside the role's allowlist is refused before it reaches the gate,
so an HR-assistant role can't be made to touch code/drive.
- applyRoleConfig fills opts.RoleScopes from the role's allowed_scopes
- the orchestrator gains allowedScopes + scopeAllows(product); empty = allow all
- handleReply refuses an out-of-scope action up front and tells the requester
it is out of the twin's lane (a capability boundary, not an approval, so safe
to surface); nothing reaches the gate or the owner
- launchConnector wires opts.RoleScopes into both orchestrators and logs the
boundary at startup
Tests: out-of-scope refused (not gated), in-scope proceeds, empty = allow all.
Sprint 2 item 2: a digital-employee role config (connect_role.go) was a
defined-but-unused schema. Wire it into the connector so a single
--role-config <file> supplies the bot's owner, persona and knowledge
sources instead of scattering them across flags.
- add --role-config / DWS_ROLE_CONFIG; load + validate in launchConnector
with a client_id-must-match-this-bot guard (one role == one bot)
- applyRoleConfig merges role -> options with explicit-flag-wins semantics
(a flag/env always overrides the role; knowledge sources are additive)
- owner feeds the approval gate; persona is prepended to every forwarded
prompt; role knowledge sources load and merge into the same retriever
- AllowedScopes / ConfirmPolicy are parsed and logged but not yet enforced
(scope gating + auto/remember strategies are a later slice; no dead opts
fields carried for them)
- tests: applyRoleConfig flag-wins / fill-empty / nil-role
Scope enforcement and confirm-policy behavior intentionally deferred.
Introduce internal/helpers/connect_role.go: a standalone configuration
component for the one-role-per-bot digital-employee model. Each role binds
to a single bot via client_id and carries its persona, knowledge sources,
allowed capability scopes, owner userId and confirmation policy.
- RoleConfig struct (YAML) with manual/auto/remember confirm policy enum.
- LoadRoleConfig: read + parse + validate with clear, non-panicking errors
(required name/client_id/owner_user_id, policy enum, source grammar).
- knowledge_sources reuse the existing parseKnowledgeSource grammar so the
schema stays in lockstep with --knowledge-source (path / wiki: / doc:).
- LoadRoleConfigs: index roles by client_id for multi-bot deployments,
rejecting duplicate client_id.
- RoleConfigExample documents a full role and is asserted in tests.
Schema only; no runtime wiring.