This commit is contained in:
+41
@@ -0,0 +1,41 @@
|
||||
# NFR Design — Logical Components (unit: ai-draft)
|
||||
|
||||
> Logical infrastructure component inventory for the ai-draft library unit. Per
|
||||
> Q2=A: ai-draft is one isolated library boundary; its blast radius is bounded
|
||||
> and its failure degrades gracefully.
|
||||
|
||||
## Component inventory
|
||||
|
||||
| Logical component | Kind | Failure domain | Blast radius |
|
||||
|---|---|---|---|
|
||||
| ai-draft (library) | library boundary | Isolated to the ai-draft process | Low — its only external effect is producing (or empty-returning) a DraftBundle; it cannot corrupt the generator or the emitted page |
|
||||
|
||||
## Boundaries & isolation
|
||||
|
||||
- **ai-draft** is a single isolated library unit (confirmed at domain-design and
|
||||
units-generation). It has no shared mutable state with the generator or funnies;
|
||||
it communicates only via the in-process DraftBrief → DraftBundle contract.
|
||||
- **Blast radius**: A failure in ai-draft (model unavailable, error, timeout) does
|
||||
not propagate to the generator's render, the funnies output, or the emitted
|
||||
page. Per the fail-soft design (Q3=A), a failure yields an empty DraftBundle +
|
||||
status message, and the generator builds the paper without AI.
|
||||
|
||||
## Component isolation strategy
|
||||
|
||||
- ai-draft depends on neither the funnies logic nor on shared infrastructure
|
||||
with the generator beyond the in-process call boundary.
|
||||
- Its only external dependency is the granted cloud model endpoint (sanctioned,
|
||||
human-approved), which is not shared with any other unit.
|
||||
|
||||
## Shared resource identification
|
||||
|
||||
- None beyond the local runtime itself. ai-draft introduces no database, cache,
|
||||
or shared queue. (See functional-design — the DraftBundle is a file handoff to
|
||||
the review page, read via the native file picker, not a shared live resource.)
|
||||
|
||||
## Bridge to Infrastructure Design
|
||||
|
||||
- The ai-draft library boundary maps to the `u2-ai-draft` build unit. No
|
||||
distributed infrastructure is required; the single model endpoint is its only
|
||||
external dependency. Failure domains are intentionally as-isolated-as-possible
|
||||
given the one-shot local-tool posture.
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
<!-- INVARIANT: examples are single-line HTML comments so a fresh template parses to total=0 (MEMORY_EMPTY). Do NOT un-comment or split across lines. t100 guards this. -->
|
||||
> This file is kept up to date automatically while the stage runs. Add observations at the review step, not by editing here directly.
|
||||
|
||||
## Interpretations
|
||||
<!-- example: 2026-05-29T10:14:32Z — chose REST over GraphQL; the consuming team only needs CRUD, revisit if subscriptions land -->
|
||||
|
||||
## Deviations
|
||||
<!-- example: 2026-05-29T10:14:32Z — skipped the optional caching layer the stage prose suggested; the dataset is small enough that it adds risk -->
|
||||
|
||||
## Tradeoffs
|
||||
<!-- example: 2026-05-29T10:14:32Z — picked TDD over BDD this run; the team is unit-first and the domain is well-understood -->
|
||||
|
||||
## Open questions
|
||||
<!-- example: 2026-05-29T10:14:32Z — confirm the retention window with compliance before the next stage hardens the schema -->
|
||||
2026-09-14T00:25:00Z — Interpretation — ai-draft NFR Design (all A): minimal-surface security, single isolated library boundary, fail-soft graceful degradation, injected structured logger. Produces security-design + logical-components + traceability (perf/scalability/reliability/observability N/A for library kind).
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
# NFR Design — Questions (unit: ai-draft)
|
||||
|
||||
> Fill in each `[Answer]:` tag. Options A-E plus X (Other). ai-draft is a
|
||||
> `library` unit: NFR Design produces security-design + logical-components +
|
||||
> traceability (perf/scalability/reliability/observability designs are
|
||||
> service-only, N/A). The confirmed ai-draft NFR targets: moderate latency,
|
||||
> strict draft-isolation, graceful fallback, light logging, Python+uv.
|
||||
|
||||
## Q1: Security pattern approach
|
||||
|
||||
The ai-draft NFR requires strict isolation (only the draft brief/text to the cloud model; nothing else leaves the machine). What security design pattern applies?
|
||||
|
||||
A) Minimal-surface — a single narrow caller to the granted model; brief built locally, minimal prompt, no secrets/credentials embedded or logged; response parsed locally (recommended)
|
||||
B) Defense-in-depth — add an explicit allow-list of the endpoint + input sanitization before the call
|
||||
C) Zero-trust style — every local→model interaction authenticated/verified
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Q2: Logical component boundary
|
||||
|
||||
As a library unit, what should `logical-components.md` capture for blast radius?
|
||||
|
||||
A) ai-draft as a single isolated library boundary — it cannot corrupt the generator/emitted page; its only external effect is producing (or empty-returning) a DraftBundle, and a failure degrades gracefully (recommended)
|
||||
B) Split ai-draft into sub-components (brief-builder, model-client, bundle-assembler) with separate failure domains
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Q3: Reliability/graceful-degradation pattern
|
||||
|
||||
The NFR says best-effort with graceful fallback (paper builds without AI). What pattern should the design specify?
|
||||
|
||||
A) A fail-soft wrapper — on model error/timeout, ai-draft returns an empty DraftBundle + status message; no retry storm; the generator proceeds without AI (recommended)
|
||||
B) Circuit-breaker style with bounded retries then fallback
|
||||
C) Retry-with-backoff a bounded number of times, then fallback
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Q4: Observability design (logical)
|
||||
|
||||
The NFR is light logging. What logging design fits a library unit?
|
||||
|
||||
A) A small structured logger the generator passes in — one concise line per draft run (requested types, success/empty status); no metrics/tracing (recommended)
|
||||
B) Built-in logging writes to stderr directly
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Consolidated Summary Confirmation
|
||||
|
||||
> Summary of the four ai-draft NFR Design answers before the unit design artifacts are generated:
|
||||
>
|
||||
> - Security pattern: **minimal-surface** — single narrow caller to the cloud model, brief built locally, no secrets (Q1=A)
|
||||
> - Logical boundary: **single isolated library** — cannot corrupt generator/page; failure degrades gracefully (Q2=A)
|
||||
> - Reliability: **fail-soft wrapper** — empty DraftBundle + status on model error, no retry storm (Q3=A)
|
||||
> - Observability: **injected structured logger** — one line per draft run (Q4=A)
|
||||
>
|
||||
> Human auto-approved summary; other units' nfr-design answers to mirror as applicable.
|
||||
|
||||
Does this all look correct before I generate the unit design artifacts?
|
||||
|
||||
- Looks correct
|
||||
- Request changes
|
||||
|
||||
[Answer]: Looks correct
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
# NFR Design — Security Design (unit: ai-draft)
|
||||
|
||||
> Minimal-surface security design for the ai-draft library unit, per Q1=A. Strict
|
||||
> isolation: only the draft brief/text to the granted cloud model; nothing else
|
||||
> leaves the machine.
|
||||
|
||||
## Approach: minimal-surface
|
||||
|
||||
- **Single narrow caller**: one thin model client in ai-draft talks only to the
|
||||
granted `deepseek-v4-flash:cloud` endpoint. No other outbound call.
|
||||
- **Brief built locally**: the DraftBrief (couple names, occasion/date, key
|
||||
themes) is assembled in-process from the content-derived context; only this
|
||||
brief + a keepsake-tone instruction travel to the model.
|
||||
- **No secrets/credentials**: no API keys, tokens, or private data are embedded,
|
||||
logged, or transmitted. Authentication (if the model endpoint needs any) comes
|
||||
from a locally-managed config the user supplies, never hard-coded.
|
||||
- **Response parsed locally**: the model's draft text is parsed into
|
||||
DraftArticle entities in-process; nothing from the response is ever executed.
|
||||
|
||||
## Design decisions
|
||||
|
||||
| Decision | Design |
|
||||
|---|---|
|
||||
| Endpoint | A single configurable model endpoint (the granted cloud model), allow-listed in ai-draft only |
|
||||
| Input to model | Minimal prompt: brief + tone instruction; nothing else |
|
||||
| Output handling | Parsed locally into structured DraftArticle(s); never evaluated/executed |
|
||||
| Logging | Light, one line per run (Q4=A); never logs brief content or secrets |
|
||||
| Secrets | None bundled; local config if endpoint auth is required |
|
||||
|
||||
## Security controls map (from ai-draft security-requirements)
|
||||
|
||||
- **NFR9.1 (strict isolation)** — satisfied by minimal-surface single-caller design.
|
||||
- **NFR9.2 (no secrets/credentials)** — satisfied by no-embedded-secrets + light logging.
|
||||
- **NFR9.3 (local-only elsewhere)** — satisfied by the single narrow external call.
|
||||
|
||||
## Verification
|
||||
|
||||
- Only one outbound call path exists in ai-draft (to the model endpoint).
|
||||
- The emitted page and DraftBundle make no network requests (NFR4).
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"stage": "nfr-design",
|
||||
"unit": "ai-draft",
|
||||
"upstream_ids": ["NFR9.1", "NFR9.2", "NFR9.3"],
|
||||
"coverage": [
|
||||
{ "id": "NFR9.1", "status": "OK", "target": "security-design.md (minimal-surface single-caller to model)" },
|
||||
{ "id": "NFR9.2", "status": "OK", "target": "security-design.md (no secrets/credentials embedded or logged)" },
|
||||
{ "id": "NFR9.3", "status": "OK", "target": "security-design.md / logical-components.md (local-only; single narrow external call)" }
|
||||
],
|
||||
"reverse": [
|
||||
{ "id": "NFR1.1", "status": "N/A", "target": "performance design is service/ui-only (library unit)" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user