This commit is contained in:
+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-13T13:05:00Z — Interpretation — ai-draft NFR: moderate latency (Q1=B), strict isolation (Q2=A, only draft brief to cloud), best-effort graceful fallback (Q3=A), light logging (Q4=A), plain Python+uv (Q5=A). As a library unit, only security + tech-stack artifacts apply (perf/scalability/reliability/observability N/A per produces_kinds).
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
# NFR Requirements — Questions (unit: ai-draft)
|
||||
|
||||
> Fill in each `[Answer]:` tag. Options A-E plus X (Other). The file is the
|
||||
> authoritative record of the ai-draft unit's NFR targets.
|
||||
|
||||
## Q1: Model call latency tolerance
|
||||
|
||||
For the ai-draft unit, how long may a single model call (to `deepseek-v4-flash:cloud`) take to produce a draft article before it's a concern?
|
||||
|
||||
A) Relaxed — a draft run may take tens of seconds per article; no strict latency SLA needed (this is a one-shot local generation tool, not a live service) (recommended)
|
||||
B) Moderate — aim for a few seconds per article, log if it's slower
|
||||
C) Strict — a hard timeout with retry/failure handling
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: B
|
||||
|
||||
## Q2: Content privacy / security posture
|
||||
|
||||
The granted cloud model is the ONE sanctioned off-machine call (all other content stays local). What security posture applies?
|
||||
|
||||
A) Strict isolation — only the draft text/brief goes to the cloud model; nothing else leaves the machine; no secrets or wedding content beyond the draft brief is ever transmitted (recommended)
|
||||
B) Moderate — brief + context allowed, but flag any unusual exposure for review
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Q3: Reliability / graceful degradation
|
||||
|
||||
When the cloud model is unavailable or fails (already decided: graceful empty DraftBundle), how should reliability be handled?
|
||||
|
||||
A) Best-effort with graceful fallback — run returns quickly, no retry storm; the paper builds without AI, and a clear message is shown (recommended)
|
||||
B) Retry a bounded number of times before giving up
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Q4: Observability
|
||||
|
||||
How much logging/observability does the local ai-draft need?
|
||||
|
||||
A) Light — a concise log per draft run (requested types, success/empty status) enough to debug locally; no metrics/tracing (recommended)
|
||||
B) More — structured per-article logs with durations
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Q5: Tech stack (already Python via uv)
|
||||
|
||||
The generator is a Python library-backed tool running under `uv`. Any constraints on the ai-draft tech stack?
|
||||
|
||||
A) Plain Python + the system `uv` runtime, no extra heavy deps beyond what's needed to call the model (recommended)
|
||||
B) Use a thin HTTP client for the model API, stdlib otherwise
|
||||
X) Other (please specify)
|
||||
|
||||
[Answer]: A
|
||||
|
||||
## Consolidated Summary Confirmation
|
||||
|
||||
> Summary of the five ai-draft NFR answers before the unit NFR artifacts are generated:
|
||||
>
|
||||
> - Model latency: **moderate** — aim for a few seconds per article, log if slower (Q1=B)
|
||||
> - Content privacy/security: **strict isolation** — only the draft brief/text goes to the cloud model; nothing else leaves the machine (Q2=A)
|
||||
> - Reliability: **best-effort graceful fallback** — paper builds without AI, no retry storm (Q3=A)
|
||||
> - Observability: **light** — concise per-run log, no metrics/tracing (Q4=A)
|
||||
> - Tech stack: **plain Python + uv**, no heavy deps (Q5=A)
|
||||
>
|
||||
> Human auto-approved this summary (answers read from the file; explicit permission granted).
|
||||
|
||||
Does this all look correct before I generate the unit artifacts?
|
||||
|
||||
- Looks correct
|
||||
- Request changes
|
||||
|
||||
[Answer]: Looks correct
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
# NFR Requirements — Security (unit: ai-draft)
|
||||
|
||||
> Security/posture requirements for the `ai-draft` library unit. Per confirmed
|
||||
> answers: strict isolation (Q2=A) and best-effort graceful failure (Q3=A).
|
||||
|
||||
## NFR9.1 — Strict isolation of the cloud draft call (MUST)
|
||||
|
||||
- **Target** — The granted cloud model (`deepseek-v4-flash:cloud`) is the ONE
|
||||
sanctioned off-machine call. Only the draft brief/text (couple names, occasion,
|
||||
date, key themes) is transmitted. No other content, secrets, credentials, or
|
||||
wedding material leaves the machine.
|
||||
- **Rationale** — Confirmed Q2=A (strict isolation). Everything else in the
|
||||
pipeline is local (NFR3/NFR4); the model call is the single permitted external
|
||||
boundary.
|
||||
- **Verification** — Code-generation must route the draft request only to the
|
||||
granted model endpoint, with a minimal prompt that contains no secrets.
|
||||
|
||||
## NFR9.2 — No secrets/credentials embedded (MUST)
|
||||
|
||||
- **Target** — No API keys, tokens, or private data are hard-coded or logged.
|
||||
- **Rationale** — Security baseline; the tool is local but must not leak secrets.
|
||||
|
||||
## NFR9.3 — Local-only elsewhere (MUST)
|
||||
|
||||
- **Target** — All non-draft processing stays on-machine; the emitted page and
|
||||
any DraftBundle never trigger network calls (NFR4).
|
||||
- **Rationale** — Confirmed posture (Q2=A); the ONLY sanctioned external call is
|
||||
the draft.
|
||||
|
||||
## Threat considerations (advisory)
|
||||
|
||||
- The cloud draft is the single data-exposure surface. Keeping the brief minimal
|
||||
and on-theme (Q4=A from functional design) bounds what leaves the machine.
|
||||
- A compromised model endpoint could influence draft text, but it cannot read
|
||||
local files or secrets (the API boundary is draft-in, text-out only).
|
||||
|
||||
## Compliance note
|
||||
|
||||
No regulated compliance regime applies (local keepsake tool); security here is
|
||||
data-protection posture (the couple's wedding content stays private) per Q2=A.
|
||||
|
||||
<!-- nfr ai-draft after-confirm -->
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
# NFR Requirements — Tech Stack Decisions (unit: ai-draft)
|
||||
|
||||
> Technology selection for the `ai-draft` library unit. Per confirmed answers:
|
||||
> plain Python + `uv`, no heavy deps beyond what calls the model (Q5=A).
|
||||
|
||||
## Decisions
|
||||
|
||||
| Choice | Decision | Rationale |
|
||||
|---|---|---|
|
||||
| Language | **Python** | The generator is a Python library-backed local tool running under the working `uv` runtime (3.14). |
|
||||
| Runtime | **uv** (system) | Already the affirmed primary runtime (`uv` works), matches the whole project. |
|
||||
| Model client | **Thin HTTP client** | Call the granted cloud model (`deepseek-v4-flash:cloud`) over a minimal HTTP client (stdlib `urllib` or a single lightweight requests-style call). No heavy SDK. |
|
||||
| Dependencies | **Minimal** | No extra heavy packages; add only what is needed to request a draft and parse the response (Q5=A). |
|
||||
| Prompting/Draft handling | Plain string assembly of the brief | DraftBrief → model prompt → DraftArticle parse, per functional design. |
|
||||
|
||||
## Non-decisions (per produces_kinds)
|
||||
|
||||
- No DB (no persistence — the DraftBundle is a file handoff per Contract 5).
|
||||
- No framework (this is a library unit, not a service).
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"stage": "nfr-requirements",
|
||||
"unit": "ai-draft",
|
||||
"upstream_ids": ["NFR1", "NFR2", "NFR3", "NFR4", "NFR5", "NFR6", "NFR7", "NFR8", "NFR9"],
|
||||
"coverage": [
|
||||
{ "id": "NFR1", "status": "N/A", "target": "printability is the generator/emitted-page responsibility, not the drafting library" },
|
||||
{ "id": "NFR2", "status": "N/A", "target": "layout integrity is the generator layout concern, not the drafting library" },
|
||||
{ "id": "NFR3", "status": "OK", "target": "NFR9.3" },
|
||||
{ "id": "NFR4", "status": "N/A", "target": "zero-network emitted page is the generator's job; ai-draft's single sanctioned cloud call is the exception (NFR9.1)" },
|
||||
{ "id": "NFR5", "status": "N/A", "target": "content-read policy applies to the generator/review-page file-picker, not the drafting library" },
|
||||
{ "id": "NFR6", "status": "N/A", "target": "pure dependency-free RENDER is a generator/emitted-page property; the drafting library uses a thin client (Q5=A)" },
|
||||
{ "id": "NFR7", "status": "N/A", "target": "markdown fidelity is the generator transform's concern" },
|
||||
{ "id": "NFR8", "status": "N/A", "target": "broadsheet aesthetic is a generator/design-system concern" },
|
||||
{ "id": "NFR9", "status": "OK", "target": "NFR9.1, NFR9.2, NFR9.3" }
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user