Skip to content

Commit e9ebd3f

Browse files
author
Corey B
committed
docs: update README, SPEC, and site for v1.2.0 — did:web workflow, trust badge, identity CLI, new CDN tag
1 parent 9c6b1c5 commit e9ebd3f

2 files changed

Lines changed: 173 additions & 74 deletions

File tree

README.md

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,33 +35,52 @@ FDD adoption solves both infrastructure and data consumption bottlenecks. We bel
3535
5. **Decentralized APIs**: Removes the massive root infrastructure cost of building API endpoints for institutions. Instead of building webhooks to support parallel and downstream industries (e.g. the mortgage industry needing bank statements, or colleges needing school records), institutions can simply issue a secure, verifiable `.fdd` file to the user.
3636

3737
## Tooling & Ecosystem Guide
38-
The OpenFDD ecosystem provides a full suite of typescript/javascript libraries to securely compose, sign, view, and inherently interact with FDD files.
38+
The OpenFDD ecosystem provides a full suite of JavaScript libraries to securely compose, sign, view, verify, and interact with FDD files.
3939

40-
### 1. Composing & Building (`node-fdd`)
41-
To build an `.fdd` file from your backend, you pack your Cryptographic JSON, your Mutable JSON, and your HTML template securely into the unified `.fdd` document wrapper:
40+
### 1. Identity & Key Generation (`node-fdd`)
41+
Before issuing documents, generate your institutional Ed25519 keypair and host your public identity:
4242
```bash
43-
# Install the Official OpenFDD CLI globally
4443
npm install -g @coreyburns/node-fdd
4544

46-
# Pack the payload securely into the FDD container
47-
fdd-pack template.html fdd-data.json user-notes.json output.fdd
45+
# Generate your Ed25519 keypair
46+
fdd-identity keygen ./keys
47+
48+
# Generate a W3C DID Document for hosting at https://yourdomain.com/.well-known/did.json
49+
fdd-identity did ./keys/public.pem yourdomain.com
4850
```
4951

50-
### 2. Cryptographic Signing
51-
If you are the official Issuer (e.g. a Bank), you must mathematically sign the JSON payload before packing it:
52+
### 2. Pack & Sign in One Step
5253
```bash
53-
fdd-sign path/to/privateKey.pem fdd-data.json
54+
# Combines packing + cryptographic signing with your issuer DID
55+
fdd-sign pack template.html data.json ./keys/private.pem did:web:yourdomain.com output.fdd
56+
```
57+
58+
Or use the programmatic API:
59+
```javascript
60+
import { generateIdentity, createDidDocument } from '@coreyburns/node-fdd/identity';
61+
import { signFdd, parse, verify } from '@coreyburns/node-fdd';
62+
63+
const identity = generateIdentity();
64+
const didDoc = createDidDocument(identity.publicKeyBase64, 'bank.com');
65+
// Host didDoc at https://bank.com/.well-known/did.json
66+
67+
// Issue a document
68+
const fddString = signFdd(data, htmlTemplate, identity.privateKeyPem, 'did:web:bank.com');
69+
70+
// Consume on a recipient server
71+
const { valid, issuer } = await verify(fddString); // resolves did:web, checks Ed25519
72+
const { vc, mutable } = parse(fddString); // extracts data, no OCR needed
5473
```
5574

56-
### 3. Parsing & Viewing Natively (`fdd-js`)
57-
To seamlessly render `.fdd` containers natively on your own web-platform without requiring plugins, simply reference the native layout library via our global jsDelivr CDN inside your DOM. It evaluates the No-JS constraints, routes Ephemeral State actions securely, and renders the Document safely!
75+
### 3. Parsing & Viewing (`fdd-js`)
76+
Render `.fdd` containers in your web platform. The library now automatically resolves the issuer's `did:web` identity and displays a cryptographic trust badge:
5877
```html
59-
<!-- Hosted securely out of explicit version tags to prevent un-authorized layout breaking -->
60-
<script src="https://cdn.jsdelivr.net/gh/Spuds0588/open-fdd@v1.1.0/lib/fdd-js/src/fdd.js"></script>
78+
<!-- Pinned to v1.2.0 — includes did:web verification & trust badge -->
79+
<script src="https://cdn.jsdelivr.net/gh/Spuds0588/open-fdd@v1.2.0/lib/fdd-js/src/fdd.js"></script>
6180
```
6281

6382
### 4. Viewing Locally (`Chrome Extension`)
64-
For End-Users navigating to FDD files natively on their disk, the custom routing extension acts as a Security Shield. It intercepts raw text rendering to sandbox the format, gracefully bypasses restrictive OS bounds allowing direct file-system saves, and actively prunes malware requests!
83+
For end-users opening `.fdd` files from disk. Acts as a Security Shield: sandboxes rendering, enables direct file-system saves, and strips malicious embedding vectors.
6584

6685
---
6786

spec/SPEC.md

Lines changed: 140 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,129 @@
1-
# The Formatted Data Document (.fdd) Specification v1.1
1+
# The Formatted Data Document (.fdd) Specification v1.2
22

33
## 1. Architectural Philosophy
44
An `.fdd` file is a "Local-First" interactive container. It treats the browser as an OS, allowing for a zero-infrastructure application experience where the file *is* the state. A document should not be a static printed picture of data (like a PDF), but rather a structured data payload wrapped seamlessly in presentation logic, natively capable of persisting its own user-driven mutations.
55

66
## 2. File Structure & Anatomy
7-
An `.fdd` file is structurally a Single-File Web App (SWA) bounded by an `<fdd-container>` wrapper. The document strictly enforces a **No-JS Security Model**. Authors are entirely forbidden from loading or executing native `<script>` logic.
7+
An `.fdd` file is structurally a Single-File Web App (SWA) bounded by an `<fdd-container>` wrapper. The document strictly enforces a **No-JS Security Model**. Authors are forbidden from loading or executing native `<script>` logic with executable MIME types.
88

99
### 2.1 The Data Segregation Model
10-
To allow for "Protected Data" alongside "Mutable Notes," FDD enforces a layered integrity architecture based on `id` routing:
10+
To allow for "Protected Data" alongside "Mutable Notes," FDD enforces a layered integrity architecture:
1111

1212
```html
1313
<fdd-container extension=".fdd">
14-
<!-- 1. Integrity Block (Cryptographically Secure) -->
14+
<!-- 1. Integrity Block (Cryptographically Signed) -->
1515
<script type="application/vc+json" id="fdd-data">
1616
{
17-
"issuer": "...",
17+
"@context": ["https://www.w3.org/2018/credentials/v1"],
18+
"type": ["VerifiableCredential"],
19+
"issuer": "did:web:bank.com",
20+
"issuanceDate": "2026-04-11T00:00:00Z",
1821
"credentialSubject": { "accountBalance": "5200.00" },
19-
"proof": { "signature": "..." }
22+
"proof": {
23+
"type": "Ed25519Signature2020",
24+
"verificationMethod": "did:web:bank.com#key-1",
25+
"signatureValue": "base64encodedSignatureHere..."
26+
}
2027
}
2128
</script>
2229

23-
<!-- 2. Local State Block (User-Writeable) -->
30+
<!-- 2. Local State Block (User-Writeable, NOT signed) -->
2431
<script type="application/json" id="user-notes">
2532
{ "followUp": "Call regarding interest rates", "contacts": [] }
2633
</script>
2734

28-
<!-- 3. Presentation Layer & Bindings -->
35+
<!-- 3. Presentation Layer -->
2936
<template shadowrootmode="open" bind="#fdd-data, #user-notes">
3037
... Declarative HTML UI ...
3138
</template>
3239
</fdd-container>
3340
```
3441

35-
## 3. The Declarative Action Framework
36-
To allow developers and AI models to build complex, reactive applications (like CRMs or banking dashboards) without violating the No-JS security constraints, OpenFDD relies on a standardized set of declarative HTML actions parsed natively by the `fdd.js` wrapper execution engine.
42+
## 3. The did:web Identity & Trust Model
3743

38-
### 3.1 Template Data Binding
39-
The presentation `<template>` is evaluated using lightweight mustache-syntax against the merged dictionaries of `#fdd-data` and `#user-notes`.
40-
* **Property Binding:** `<h1>{{accountBalance}}</h1>`
41-
* **Array Iteration:** Use `{{#each arrayName}}` to iterate over nested objects. Within an iterative loop, the parser natively routes the `{{@index}}` tag to identify the active object's array index natively.
44+
### 3.1 Issuer Identity (did:web)
45+
Every `.fdd` document identifies its issuer using the `did:web` DID method. The issuer hosts a public key at a well-known URL, and any viewer can automatically resolve it to verify the document's authenticity.
46+
47+
- **Issuer URI format:** `did:web:yourdomain.com`
48+
- **Public key endpoint:** `https://yourdomain.com/.well-known/did.json`
49+
50+
### 3.2 Generating an Identity (One-Time Setup)
51+
52+
```bash
53+
# Generate Ed25519 keypair
54+
fdd-identity keygen ./keys
55+
56+
# Generate the did.json to host publicly
57+
fdd-identity did ./keys/public.pem yourdomain.com
58+
# → Upload did.json to https://yourdomain.com/.well-known/did.json
59+
```
60+
61+
Or via the programmatic API:
62+
```javascript
63+
import { generateIdentity, createDidDocument } from '@coreyburns/node-fdd/identity';
64+
65+
const identity = generateIdentity();
66+
// Returns: { privateKeyPem, publicKeyPem, publicKeyBase64 }
67+
68+
const didDoc = createDidDocument(identity.publicKeyBase64, 'bank.com');
69+
// Returns W3C DID Document — host at https://bank.com/.well-known/did.json
70+
```
71+
72+
### 3.3 Issuing a Document (Per-Document)
73+
74+
```bash
75+
fdd-sign pack template.html data.json ./keys/private.pem did:web:bank.com output.fdd
76+
```
77+
78+
Or via API:
79+
```javascript
80+
import { signFdd } from '@coreyburns/node-fdd';
81+
82+
const fddString = signFdd(credentialSubjectData, htmlTemplate, privateKeyPem, 'did:web:bank.com');
83+
// Returns a complete .fdd file string, ready to save or send
84+
```
85+
86+
The signed payload covers **both** the Verifiable Credential data and the HTML template. Tampering with either invalidates the signature.
87+
88+
### 3.4 Consuming a Document (Recipient)
89+
90+
```javascript
91+
import { parse, verify } from '@coreyburns/node-fdd';
92+
93+
// Server-side verification — resolves did:web, fetches public key, checks Ed25519
94+
const { valid, issuer } = await verify(fddString);
95+
96+
// Zero-OCR data extraction
97+
const { vc, mutable } = parse(fddString);
98+
```
99+
100+
### 3.5 Client-Side Trust Badge (fdd-js)
101+
When a document is rendered in the browser, `fdd-js` automatically:
102+
1. Reads the `proof.verificationMethod` from the VC block.
103+
2. Resolves the `did:web` URI → fetches `/.well-known/did.json`.
104+
3. Imports the public key via the **Web Crypto API** (Ed25519).
105+
4. Verifies the signature and injects a **Trust Badge** into the document:
106+
107+
| Badge State | Meaning |
108+
|---|---|
109+
| 🔍 Checking… | DID resolution in progress |
110+
| ✅ Verified | Signature valid, issuer confirmed |
111+
| ⚠️ Invalid | Document tampered or signature mismatch |
112+
| ❓ Unresolved | DID endpoint unavailable |
113+
114+
The trust badge renders **non-blocking** — documents always display immediately.
115+
116+
## 4. The Declarative Action Framework
117+
To allow developers to build complex, reactive applications without violating the No-JS security constraints, OpenFDD relies on standardized declarative HTML actions.
118+
119+
### 4.1 Template Data Binding
120+
The `<template>` is evaluated using Mustache-syntax against the merged `#fdd-data` and `#user-notes` dictionaries.
42121

43122
```html
123+
<!-- Property binding -->
124+
<h1>{{accountBalance}}</h1>
125+
126+
<!-- Array iteration -->
44127
{{#each contacts}}
45128
<div class="card">
46129
<h2>{{name}}</h2>
@@ -49,49 +132,46 @@ The presentation `<template>` is evaluated using lightweight mustache-syntax aga
49132
{{/each}}
50133
```
51134

52-
### 3.2 State Mutations & Interactions
53-
The parser intercepts standard DOM elements annotated with `fdd-target` attributes explicitly mapping back to the mutable `#user-notes` JSON block. (Mutations targeting `#fdd-data` will trigger native compilation warnings and fail silently during run-time execution to protect cryptographic signature thresholds).
54-
55-
* **Auto-Save Inputs:** Appending the `autosave` attribute to an `<input>` or `<textarea>` maps real-time keystrokes securely back to the file state.
56-
* `<textarea name="user-notes.followUp" autosave>{{followUp}}</textarea>`
57-
* **Array Pushes:** Standard HTML forms perfectly interact with FDD schemas to append structured objects into an array securely without scripts.
58-
* `<form fdd-action="push" fdd-target="user-notes.contacts">`
59-
* **Property Setters:** Custom `<button>` elements can declaratively rewrite explicit local variables or deep-nested objects.
60-
* `<button fdd-action="set" fdd-target="user-notes.contacts.{{@index}}.archived" fdd-value="true">Archive Contact</button>`
61-
62-
### 3.3 Ephemeral State & Conditional Routing (The UI-State)
63-
To track complex "Transient View State" (like actively modifying a contact card or swapping pages) without routinely spamming the user's hard-drive, OpenFDD provides an ephemeral rendering router detached entirely from the persistent `#user-notes` schema: `ui-state`.
64-
65-
* **Setting Active View State:** `<button fdd-action="set-ui" fdd-target="selectedTab" fdd-value="contacts">`
66-
* **Deep Contextual Rendering Layouts:** Use `fdd-match` to explicitly isolate deep layout injections strictly to the target UI route!
67-
```html
68-
<div class="editor" fdd-match="ui.selectedTab" fdd-value="contacts">
69-
<!-- Renders ONLY when that specific UI state matches without firing Save Warnings -->
70-
</div>
71-
```
72-
* **Conditional Pruning:** Explicit boolean DOM exclusions are natively built into the standard mapping loop logic:
73-
* `<span fdd-if="{{isVerified}}">Certified</span>`
74-
* `<span fdd-unless="{{archived}}">Active Pipeline Target</span>`
75-
76-
## 4. The Self-Saving Persistence Mechanism
77-
An `.fdd` file acts as its own state database. Updates to the DOM efficiently sync back to the originating `.fdd` file natively.
78-
79-
* **Primary Strategy (File System Access API):** The `.fdd` parser bounds interactive changes to an explicit file-handle write-lock approval prompt on initial layout bounds. If granted, mutable components actively rewrite the local file.
80-
* **Universal Fallback (The Save Pattern):** Because native write-locks are routinely restricted (e.g., Linux sandbox environments / URI contexts), the FDD specification standardizes a uniform "Save Updates" interface overlay. When active edits mutate the DOM, a persistent prompt alerts the user without interfering in the UI layout. Committing the respective save actively leverages ambient location hooks to definitively default the internal OS download to actively match the originating `.fdd`'s explicit filename!
81-
82-
## 5. Security Model & The Hidden Ink Risk
83-
Since executable scripts are stripped, interactions scale solely through CSS Pseudo Types (`:checked`, `:hover`) and the rigid Declarative Action framework documented above.
84-
85-
### 5.1 The "Hidden Ink" Presentation Risk
86-
Because OpenFDD utilizes declarative CSS for structural templating, there inherently exists a layout spoofing vector (e.g., deliberately matching text properties to background bounds, or hiding blocks via `display: none` to actively conceal contractual obligations).
87-
88-
To heavily mitigate this vector, OpenFDD formally separates the **Integrity Layer** (`#fdd-data`) from the loosely defined **Presentation Layer** (`<template>`).
89-
* Authoritative `.fdd` viewers **SHOULD** proactively implement accessibility contrast safeguards, OR securely expose a persistent "Raw Data Inspector" UI guaranteeing immediate visibility towards the un-styled, pristine JSON structure.
90-
* **The Governing Principle:** Presentation is merely a convenience; the raw cryptographically signed `#fdd-data` layer asserts the absolute legal source of truth.
91-
92-
## 6. The Advocacy Roadmap
93-
To establish `.fdd` ubiquity across browsers and SaaS ecosystems:
94-
1. **The "Trust Tier" Proposal:** Lobby W3C/WICG to explicitly configure Zero-JS containers securely to bypass the rampant "Permission Fatigue" common among local-first web app strategies.
95-
2. **The "AI Grounding" Certification:** Forcefully position `.fdd` outputs as the prime injection metric for generative LLMs structure mapping, aggressively supplanting hallucinatory OCR-bound PDF scrapes with cryptographically pristine JSON-LD payloads.
96-
3. **SaaS "Off-Ramp" Continuity:** Persuade leading core Enterprise architectures (Hubspot/Salesforce) to route client exports into highly interactive `.fdd` single-file-apps rather than static, un-recyclable PDF forms.
97-
4. **The Safe Universal Reader:** Systematically deploy a highly accessible PWA handler catching default OS interactions while strategically routing telemtry insights towards browser vendor implementations natively.
135+
### 4.2 State Mutations & Interactions
136+
The parser intercepts DOM elements annotated with `fdd-*` attributes that map to the mutable `#user-notes` block. Mutations targeting `#fdd-data` (the signed block) will trigger compiler warnings and fail silently at runtime.
137+
138+
- **Auto-Save Inputs:** `<textarea name="user-notes.followUp" autosave>{{followUp}}</textarea>`
139+
- **Array Push:** `<form fdd-action="push" fdd-target="user-notes.contacts">`
140+
- **Property Setter:** `<button fdd-action="set" fdd-target="user-notes.contacts.{{@index}}.archived" fdd-value="true">Archive</button>`
141+
- **Array Delete:** `<button fdd-action="delete" fdd-target="user-notes.contacts" fdd-index="{{@index}}">`
142+
143+
### 4.3 Ephemeral UI State
144+
Track complex view state (tabbing, expanded cards) without touching the persisted file:
145+
146+
```html
147+
<button fdd-action="set-ui" fdd-target="selectedTab" fdd-value="contacts">Contacts</button>
148+
149+
<div fdd-match="ui.selectedTab" fdd-value="contacts">
150+
<!-- Renders ONLY when selectedTab === "contacts" -->
151+
</div>
152+
```
153+
154+
Conditional rendering:
155+
- `<span fdd-if="{{isVerified}}">Certified</span>`
156+
- `<span fdd-unless="{{archived}}">Active</span>`
157+
158+
## 5. The Self-Saving Persistence Mechanism
159+
- **Primary (File System Access API):** The parser requests a write-lock on first interaction. If granted, mutations auto-sync to the local file.
160+
- **Fallback (Save Banner):** A persistent "Save Updates" overlay downloads the updated `.fdd` file matching the original filename when the API is unavailable.
161+
162+
## 6. Security Model
163+
164+
### 6.1 Zero-Trust Embedding Policy
165+
The compiler (`fdd-pack`) **fatally rejects** templates containing: `<script>`, `<iframe>`, `<object>`, `<embed>`, `<applet>`. The runtime parsers (`fdd-js`, `content.js`) additionally scrub any such elements from the Declarative Shadow DOM before rendering.
166+
167+
### 6.2 The "Hidden Ink" Presentation Risk
168+
CSS can be used to visually conceal content (e.g., matching foreground to background colors). Authoritative viewers **SHOULD** implement a "Raw Data Inspector" that exposes the unstyled `#fdd-data` JSON — the cryptographically signed block is the **legal source of truth**, not the visual presentation.
169+
170+
### 6.3 The Private Key Boundary
171+
The private key **never** leaves the issuer's server. The public key is always available via the `did:web` endpoint for open verification. A bad actor cannot forge a document without compromising the issuer's actual web domain.
172+
173+
## 7. The Advocacy Roadmap
174+
1. **The "Trust Tier" Proposal:** Lobby W3C/WICG to configure Zero-JS containers as high-trust sandboxes, reducing "Permission Fatigue" for local-first web apps.
175+
2. **AI Grounding:** Position `.fdd` as the canonical input format for LLMs — cryptographically pristine JSON-LD beats hallucinatory OCR-bound PDF scrapes.
176+
3. **SaaS Off-Ramp:** Persuade Hubspot, Salesforce, and similar platforms to export to `.fdd` instead of static PDFs.
177+
4. **Native Browser Support:** Systematically campaign for `.fdd` to be treated as a first-class file type alongside `.pdf` in Chrome, Firefox, and Safari.

0 commit comments

Comments
 (0)