Skip to content

Use stricter Arc42 format for architectural decisions #79

@LeoVS09

Description

@LeoVS09

In current version of software architect agent shifted his format for architectural decisions, after Opus 4.6 release. Need define stricter format that closer resembles Arc42 specification.

Example

### Architecture Decisions

#### Use Custom authenticate() Override Instead of validate()

**Status**: Accepted

**Context**: Need to implement Bearer token extraction from Authorization header in a Passport strategy.

**Options**:
1. Override `authenticate()` on base `Strategy` from `passport` -- full control over header extraction
2. Use `validate()` with `passport-custom` -- delegates req to validate, extra dependency
3. Use `validate()` with custom header extraction via Passport options -- not supported for base Strategy

**Decision**: Override `authenticate()` on base `Strategy`. When `authenticate()` is overridden, `validate()` is NOT called. This is the recommended approach from the skill file. Since we read the Authorization header ourselves, `authenticate()` is the correct method. Must call `this.success()`, `this.fail()`, or `this.error()` manually.

**Consequences**:
- No need for `passport-custom` dependency (fewer deps)
- Full control over header parsing and error messages
- Must remember to call `this.success()`/`this.fail()` -- not throwing exceptions

#### Apply Guards at Resolver Class Level (Not Global, Not Method-Level)

**Status**: Accepted

**Context**: Need to protect both GraphQL resolvers (verification and decision), each with one method.

**Options**:
1. Class-level `@UseGuards(GqlAuthGuard)` on each resolver
2. Method-level `@UseGuards(GqlAuthGuard)` on each query/mutation
3. Global guard via `APP_GUARD` with `@Public()` decorator for health endpoints

**Decision**: Class-level guards. Both resolvers have exactly one method. Class-level is cleaner and protects future methods by default. Global guard is over-engineered for 2 resolvers; health endpoints are HTTP controllers (not GQL) so a global GQL guard would not affect them anyway.

**Consequences**:
- Any new method added to these resolvers is automatically protected
- Each resolver file clearly shows it requires authentication at the class level
- Simpler than global guard approach (no `@Public()` decorator needed)

Alternative

Possible to improve it by rearranging sections, to force model think about consequences before making decision. It should look like this:

#### Decision Title
**Context**: ...

**Options**
1. Option A - ....
   Consequences:
   - Consequence 1
   - Consequence 2
   - Consequence 3
 2. Option B - ...
   Consequences:
   - Consequence 1
   - Consequence 2
   - Consequence 3

**Reasoning**: 
- ...
- ...

**Decision**: ....

Maybe even better to add Risks, Pluses and Cons sections, in scratchpad but exclude it from Specification Decision section

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions