This commit is contained in:
+42
@@ -0,0 +1,42 @@
|
||||
# NFR Design — Logical Components (unit: funnies)
|
||||
|
||||
> Logical infrastructure component inventory for the funnies library unit. Per
|
||||
> Q2=A: funnies is one isolated library boundary; its blast radius is bounded
|
||||
> and its failure degrades gracefully to a tasteful placeholder.
|
||||
|
||||
## Component inventory
|
||||
|
||||
| Logical component | Kind | Failure domain | Blast radius |
|
||||
|---|---|---|---|
|
||||
| funnies (library) | library boundary | Isolated to the funnies process | Low — produces (or fallback-returns) a FunniesResult; cannot corrupt the generator or emitted page |
|
||||
|
||||
## Boundaries & isolation
|
||||
|
||||
- **funnies** is a single isolated library unit (confirmed at domain-design and
|
||||
units-generation). It has no shared mutable state with the generator or
|
||||
ai-draft; it communicates only via the in-process FunniesBrief → FunniesResult
|
||||
contract.
|
||||
- **Blast radius**: A failure in funnies (fetch/puzzle error, no viable content)
|
||||
does not propagate to the generator's render, the ai-draft output, or the
|
||||
emitted page. Per the fail-soft design (Q3=A), it returns a fallback/empty
|
||||
FunniesResult + status message, and the generator embeds it gracefully.
|
||||
|
||||
## Component isolation strategy
|
||||
|
||||
- funnies depends on neither the ai-draft logic nor shared infrastructure with
|
||||
the generator beyond the in-process call boundary.
|
||||
- Its only external dependency is the allowed cartoon/comic content-enrichment
|
||||
source (sanctioned), which is not shared with any other unit.
|
||||
|
||||
## Shared resource identification
|
||||
|
||||
- None beyond the local runtime itself. funnies introduces no database, cache,
|
||||
or shared queue. (FunniesResult is a data artifact consumed by the generator,
|
||||
not a shared live resource.)
|
||||
|
||||
## Bridge to Infrastructure Design
|
||||
|
||||
- The funnies library boundary maps to the `u3-funnies` build unit. No
|
||||
distributed infrastructure is required; the single allowed content-enrichment
|
||||
source is its only external dependency. Failure domains are 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:26:00Z — Interpretation — funnies NFR Design (mirror ai-draft, all A): minimal-surface security (single narrow fetch), single isolated library boundary, fail-soft graceful degradation, injected structured logger. Produces security-design + logical-components + traceability.
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
# NFR Design — Questions (unit: funnies)
|
||||
|
||||
> Fill in each `[Answer]:` tag. funnies is a `library` unit: NFR Design produces
|
||||
> security-design + logical-components + traceability (perf/scalability/
|
||||
> reliability/observability designs are service-only, N/A). Answers mirror
|
||||
> ai-draft (human standing instruction) with funnies-appropriate context: the
|
||||
> one sanctioned external call is the cartoon/comic content-enrichment fetch.
|
||||
|
||||
## Q1: Security pattern approach
|
||||
|
||||
funnies' NFR requires strict isolation of the cartoon/comic fetch (only the context-search query leaves; assets embedded locally). What security design pattern applies?
|
||||
|
||||
A) Minimal-surface — a single narrow fetch client to the allowed cartoon/comic source; context query built locally; fetched asset embedded locally; nothing else leaves the machine (recommended)
|
||||
B) Defense-in-depth — explicit allow-list of the source + input sanitization before the fetch
|
||||
C) Zero-trust style — every local→source 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) funnies as a single isolated library boundary — it cannot corrupt the generator/emitted page; its only external effect is producing (or fallback-returning) a FunniesResult; a failure degrades gracefully to a tasteful placeholder/empty (recommended)
|
||||
B) Split funnies into sub-components (puzzle-builder, fetch-client, cartoon-selector) with separate failure domains
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Q3: Reliability/graceful-degradation pattern
|
||||
|
||||
funnies' NFR says best-effort with graceful fallback. What pattern should the design specify?
|
||||
|
||||
A) A fail-soft wrapper — on fetch/puzzle failure, funnies returns a fallback/empty FunniesResult + status message; no retry storm; the generator embeds it gracefully (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)
|
||||
|
||||
funnies' NFR is light logging. What logging design fits a library unit?
|
||||
|
||||
A) A small structured logger the generator passes in — one concise line per section build (crossword/find-a-word/cartoon status + fallback triggers); 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 funnies NFR Design answers (mirror ai-draft, human-approved):
|
||||
>
|
||||
> - Security: minimal-surface (single narrow fetch, embedded locally)
|
||||
> - Logical boundary: single isolated library, graceful fallback
|
||||
> - Reliability: fail-soft wrapper, no retry storm
|
||||
> - Observability: injected structured logger, one line per section build
|
||||
>
|
||||
> Human auto-approved.
|
||||
|
||||
Does this all look correct before I generate the unit design artifacts?
|
||||
|
||||
- Looks correct
|
||||
- Request changes
|
||||
|
||||
[Answer]: Looks correct
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
# NFR Design — Security Design (unit: funnies)
|
||||
|
||||
> Minimal-surface security design for the funnies library unit, per Q1=A. Strict
|
||||
> isolation: only the cartoon/comic content-enrichment fetch is allowed; assets
|
||||
> are embedded locally; nothing else leaves the machine.
|
||||
|
||||
## Approach: minimal-surface
|
||||
|
||||
- **Single narrow fetch client**: one thin fetch client in funnies talks only to
|
||||
the allowed cartoon/comic source (real-xkcd / selected source). No other
|
||||
outbound call.
|
||||
- **Context query built locally**: the cartoon-search context (content-derived
|
||||
themes/occasion) is assembled in-process; only that query travels.
|
||||
- **Fetched asset embedded locally**: the fetched cartoon/comic is copied to a
|
||||
local bundled asset; the emitted page never references a remote URL (NFR4).
|
||||
- **No secrets/credentials**: no keys/tokens/private data embedded, logged, or
|
||||
transmitted. The fetch is unauthenticated against the allowed public source.
|
||||
- **Graceful no-result**: if the fetch fails/returns nothing useful, funnies
|
||||
falls back to a tasteful content-derived strip (never a remote URL at print).
|
||||
|
||||
## Design decisions
|
||||
|
||||
| Decision | Design |
|
||||
|---|---|
|
||||
| Fetch source | A configurable allowed source (real-xkcd / selected); not hard-coded to a secret endpoint |
|
||||
| Input to fetch | Minimal context query; no secrets |
|
||||
| Result handling | Downloaded + embedded locally; never kept as a remote dependency |
|
||||
| Logging | Light, one line per section (Q4=A); never logs query content or secrets |
|
||||
| Secrets | None |
|
||||
|
||||
## Security controls map (from funnies security-requirements)
|
||||
|
||||
- **NFR9.1 (allowed fetch only)** — satisfied by minimal-surface single-fetch design.
|
||||
- **NFR9.2 (no secrets/credentials)** — satisfied by no-embedded-secrets + light logging.
|
||||
- **NFR9.3 (local-only elsewhere)** — satisfied by the single narrow external fetch; puzzle layout is fully local.
|
||||
|
||||
## Verification
|
||||
|
||||
- Only one outbound fetch path in funnies (to the allowed cartoon/comic source).
|
||||
- The emitted page and funnies output make zero network requests (NFR4).
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"stage": "nfr-design",
|
||||
"unit": "funnies",
|
||||
"upstream_ids": ["NFR9.1", "NFR9.2", "NFR9.3"],
|
||||
"coverage": [
|
||||
{ "id": "NFR9.1", "status": "OK", "target": "security-design.md (minimal-surface single fetch client)" },
|
||||
{ "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 fetch)" }
|
||||
],
|
||||
"reverse": [
|
||||
{ "id": "NFR1.1", "status": "N/A", "target": "performance design is service/ui-only (library unit)" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user