@ternent/core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/README.md +8 -0
- package/.changeset/config.json +17 -0
- package/.github/workflows/deploy-armour.yml +42 -0
- package/.github/workflows/deploy-identity.yml +42 -0
- package/.github/workflows/deploy-seal.yml +42 -0
- package/.github/workflows/deploy-ui.yml +42 -0
- package/.github/workflows/deploy-utils.yml +42 -0
- package/.github/workflows/release-create.yml +59 -0
- package/.github/workflows/release-publish.yml +54 -0
- package/.nvmrc +1 -0
- package/.ops/publish.mjs +31 -0
- package/package.json +16 -0
- package/packages/README.md +0 -0
- package/packages/armour/CHANGELOG.md +66 -0
- package/packages/armour/CLAUDE.md +8 -0
- package/packages/armour/README.md +103 -0
- package/packages/armour/SPEC.md +92 -0
- package/packages/armour/package.json +45 -0
- package/packages/armour/src/constants.ts +5 -0
- package/packages/armour/src/deps.d.ts +56 -0
- package/packages/armour/src/errors.ts +172 -0
- package/packages/armour/src/files.ts +73 -0
- package/packages/armour/src/identity.ts +72 -0
- package/packages/armour/src/index.ts +56 -0
- package/packages/armour/src/init.ts +10 -0
- package/packages/armour/src/passphrase.ts +33 -0
- package/packages/armour/src/recipients.ts +73 -0
- package/packages/armour/src/text.ts +68 -0
- package/packages/armour/src/types.ts +93 -0
- package/packages/armour/test/armour.test.ts +270 -0
- package/packages/armour/tsconfig.build.json +12 -0
- package/packages/armour/tsconfig.json +12 -0
- package/packages/armour/vite.config.ts +29 -0
- package/packages/concord/CHANGELOG.md +83 -0
- package/packages/concord/CLAUDE.md +9 -0
- package/packages/concord/README.md +146 -0
- package/packages/concord/SPEC.md +287 -0
- package/packages/concord/package.json +51 -0
- package/packages/concord/src/app.ts +717 -0
- package/packages/concord/src/errors.ts +9 -0
- package/packages/concord/src/index.ts +20 -0
- package/packages/concord/src/types.ts +127 -0
- package/packages/concord/test/concord.test.ts +978 -0
- package/packages/concord/tsconfig.json +12 -0
- package/packages/concord/vite.browser.config.ts +27 -0
- package/packages/concord/vite.config.ts +35 -0
- package/packages/concord/vite.config.ts.timestamp-1774262297922-ffd76e35ea668.mjs +83 -0
- package/packages/identity/CHANGELOG.md +47 -0
- package/packages/identity/README.md +236 -0
- package/packages/identity/package.json +41 -0
- package/packages/identity/src/index.ts +538 -0
- package/packages/identity/test/identity.test.ts +172 -0
- package/packages/identity/tsconfig.build.json +12 -0
- package/packages/identity/vite.config.ts +17 -0
- package/packages/ledger/CHANGELOG.md +69 -0
- package/packages/ledger/CLAUDE.md +9 -0
- package/packages/ledger/SPEC.md +304 -0
- package/packages/ledger/package.json +48 -0
- package/packages/ledger/src/index.ts +2 -0
- package/packages/ledger/src/ledger.ts +1286 -0
- package/packages/ledger/src/seal-cli.d.ts +25 -0
- package/packages/ledger/src/types.ts +294 -0
- package/packages/ledger/test/ledger.test.ts +838 -0
- package/packages/ledger/tsconfig.json +12 -0
- package/packages/ledger/vite.browser.config.ts +27 -0
- package/packages/ledger/vite.config.ts +39 -0
- package/packages/seal/CHANGELOG.md +137 -0
- package/packages/seal/CLAUDE.md +8 -0
- package/packages/seal/README.md +258 -0
- package/packages/seal/bin/seal +6 -0
- package/packages/seal/package.json +59 -0
- package/packages/seal/src/artifact.ts +380 -0
- package/packages/seal/src/cli.ts +372 -0
- package/packages/seal/src/commands/identity.ts +52 -0
- package/packages/seal/src/commands/manifest.ts +71 -0
- package/packages/seal/src/commands/publicKey.ts +7 -0
- package/packages/seal/src/commands/sign.ts +56 -0
- package/packages/seal/src/commands/verify.ts +54 -0
- package/packages/seal/src/crypto.ts +85 -0
- package/packages/seal/src/errors.ts +88 -0
- package/packages/seal/src/index.ts +5 -0
- package/packages/seal/src/manifest.ts +114 -0
- package/packages/seal/src/node.ts +18 -0
- package/packages/seal/src/proof.ts +344 -0
- package/packages/seal/test/artifact.test.ts +86 -0
- package/packages/seal/test/cli.test.ts +208 -0
- package/packages/seal/test/crypto.test.ts +21 -0
- package/packages/seal/test/manifest.test.ts +32 -0
- package/packages/seal/test/proof.test.ts +60 -0
- package/packages/seal/tsconfig.json +12 -0
- package/packages/seal/vite.config.ts +54 -0
- package/packages/ui/CHANGELOG.md +393 -0
- package/packages/ui/README.md +57 -0
- package/packages/ui/jsconfig.json +19 -0
- package/packages/ui/package.json +64 -0
- package/packages/ui/scripts/check-tokens.js +56 -0
- package/packages/ui/scripts/generate-theme-css.mjs +85 -0
- package/packages/ui/src/design-system/base.css +8 -0
- package/packages/ui/src/design-system/docs/ACCESSIBILITY_RULES.md +186 -0
- package/packages/ui/src/design-system/docs/AI_SYSTEM.md +281 -0
- package/packages/ui/src/design-system/docs/PATTERN_RULES.md +83 -0
- package/packages/ui/src/design-system/docs/PRIMITIVE_RULES.md +258 -0
- package/packages/ui/src/design-system/docs/TOKEN_RULES.md +235 -0
- package/packages/ui/src/design-system/docs/VISUAL_DIRECTION.md +68 -0
- package/packages/ui/src/design-system/foundation.js +420 -0
- package/packages/ui/src/design-system/tokens.css +140 -0
- package/packages/ui/src/design-system/tokens.js +327 -0
- package/packages/ui/src/design-system/utils.js +246 -0
- package/packages/ui/src/main.js +4 -0
- package/packages/ui/src/patterns/FeatureCard/FeatureCard.spec.md +24 -0
- package/packages/ui/src/patterns/FeatureCard/FeatureCard.types.ts +8 -0
- package/packages/ui/src/patterns/FeatureCard/FeatureCard.vue +175 -0
- package/packages/ui/src/patterns/FormField/FormField.spec.md +65 -0
- package/packages/ui/src/patterns/FormField/FormField.types.ts +11 -0
- package/packages/ui/src/patterns/FormField/FormField.vue +87 -0
- package/packages/ui/src/patterns/IdentityGlyph/IdentityGlyph.vue +61 -0
- package/packages/ui/src/patterns/IdentityGlyph/IdentityHandle.vue +58 -0
- package/packages/ui/src/patterns/IdentityGlyph/identityGlyph.types.ts +36 -0
- package/packages/ui/src/patterns/IdentityGlyph/identityGlyph.utils.ts +585 -0
- package/packages/ui/src/patterns/IdentityGlyph/index.ts +5 -0
- package/packages/ui/src/patterns/KeyValueList/KeyValueList.spec.md +28 -0
- package/packages/ui/src/patterns/KeyValueList/KeyValueList.types.ts +16 -0
- package/packages/ui/src/patterns/KeyValueList/KeyValueList.vue +50 -0
- package/packages/ui/src/patterns/LandingPage/LandingIcon.vue +90 -0
- package/packages/ui/src/patterns/LandingPage/LandingPage.spec.md +24 -0
- package/packages/ui/src/patterns/LandingPage/LandingPage.types.ts +212 -0
- package/packages/ui/src/patterns/LandingPage/LandingPage.vue +599 -0
- package/packages/ui/src/patterns/ListWorkspaceLayout/ListWorkspaceLayout.test.ts +33 -0
- package/packages/ui/src/patterns/ListWorkspaceLayout/ListWorkspaceLayout.vue +44 -0
- package/packages/ui/src/patterns/Logo/Logo.spec.md +22 -0
- package/packages/ui/src/patterns/Logo/Logo.vue +160 -0
- package/packages/ui/src/patterns/PageSurface/PageSurface.spec.md +15 -0
- package/packages/ui/src/patterns/PageSurface/PageSurface.vue +85 -0
- package/packages/ui/src/patterns/PanelChrome/PanelChrome.spec.md +39 -0
- package/packages/ui/src/patterns/PanelChrome/PanelChrome.types.ts +1 -0
- package/packages/ui/src/patterns/PanelChrome/PanelChrome.vue +187 -0
- package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.spec.md +31 -0
- package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.types.ts +23 -0
- package/packages/ui/src/patterns/PreviewPanel/PreviewPanel.vue +354 -0
- package/packages/ui/src/patterns/RecordList/RecordList.spec.md +35 -0
- package/packages/ui/src/patterns/RecordList/RecordList.test.ts +42 -0
- package/packages/ui/src/patterns/RecordList/RecordList.types.ts +9 -0
- package/packages/ui/src/patterns/RecordList/RecordList.utils.ts +5 -0
- package/packages/ui/src/patterns/RecordList/RecordList.vue +134 -0
- package/packages/ui/src/patterns/SectionClarifier/SectionClarifier.vue +85 -0
- package/packages/ui/src/patterns/SectionIntro/SectionIntro.spec.md +25 -0
- package/packages/ui/src/patterns/SectionIntro/SectionIntro.types.ts +7 -0
- package/packages/ui/src/patterns/SectionIntro/SectionIntro.vue +141 -0
- package/packages/ui/src/patterns/SidebarNav/SidebarNav.spec.md +34 -0
- package/packages/ui/src/patterns/SidebarNav/SidebarNav.types.ts +17 -0
- package/packages/ui/src/patterns/SidebarNav/SidebarNav.vue +110 -0
- package/packages/ui/src/patterns/SplitView/SplitView.spec.md +28 -0
- package/packages/ui/src/patterns/SplitView/SplitView.test.ts +22 -0
- package/packages/ui/src/patterns/SplitView/SplitView.types.ts +3 -0
- package/packages/ui/src/patterns/SplitView/SplitView.utils.ts +13 -0
- package/packages/ui/src/patterns/SplitView/SplitView.vue +39 -0
- package/packages/ui/src/patterns/StepList/StepList.spec.md +15 -0
- package/packages/ui/src/patterns/StepList/StepList.types.ts +4 -0
- package/packages/ui/src/patterns/StepList/StepList.vue +91 -0
- package/packages/ui/src/patterns/Verification/VerificationBadge.vue +97 -0
- package/packages/ui/src/patterns/Verification/VerificationComponents.test.ts +153 -0
- package/packages/ui/src/patterns/Verification/VerificationDetailsPanel.vue +270 -0
- package/packages/ui/src/patterns/Verification/VerificationSummary.vue +171 -0
- package/packages/ui/src/patterns/Verification/index.ts +6 -0
- package/packages/ui/src/patterns/Verification/verification.types.ts +8 -0
- package/packages/ui/src/patterns/Verification/verification.utils.test.ts +37 -0
- package/packages/ui/src/patterns/Verification/verification.utils.ts +75 -0
- package/packages/ui/src/patterns/index.ts +25 -0
- package/packages/ui/src/primitives/Accordian/Accordian.vue +11 -0
- package/packages/ui/src/primitives/Accordian/AccordianItem.vue +14 -0
- package/packages/ui/src/primitives/Accordion/Accordion.props.ts +21 -0
- package/packages/ui/src/primitives/Accordion/Accordion.spec.md +50 -0
- package/packages/ui/src/primitives/Accordion/Accordion.types.ts +4 -0
- package/packages/ui/src/primitives/Accordion/Accordion.variants.ts +12 -0
- package/packages/ui/src/primitives/Accordion/Accordion.vue +71 -0
- package/packages/ui/src/primitives/Accordion/AccordionItem.props.ts +14 -0
- package/packages/ui/src/primitives/Accordion/AccordionItem.vue +40 -0
- package/packages/ui/src/primitives/Badge/Badge.props.ts +17 -0
- package/packages/ui/src/primitives/Badge/Badge.spec.md +17 -0
- package/packages/ui/src/primitives/Badge/Badge.types.ts +15 -0
- package/packages/ui/src/primitives/Badge/Badge.variants.ts +48 -0
- package/packages/ui/src/primitives/Badge/Badge.vue +31 -0
- package/packages/ui/src/primitives/Button/Button.props.ts +29 -0
- package/packages/ui/src/primitives/Button/Button.spec.md +139 -0
- package/packages/ui/src/primitives/Button/Button.types.ts +19 -0
- package/packages/ui/src/primitives/Button/Button.variants.ts +72 -0
- package/packages/ui/src/primitives/Button/Button.vue +90 -0
- package/packages/ui/src/primitives/Card/Card.props.ts +17 -0
- package/packages/ui/src/primitives/Card/Card.spec.md +29 -0
- package/packages/ui/src/primitives/Card/Card.types.ts +12 -0
- package/packages/ui/src/primitives/Card/Card.variants.ts +27 -0
- package/packages/ui/src/primitives/Card/Card.vue +37 -0
- package/packages/ui/src/primitives/Checkbox/Checkbox.props.ts +21 -0
- package/packages/ui/src/primitives/Checkbox/Checkbox.spec.md +51 -0
- package/packages/ui/src/primitives/Checkbox/Checkbox.types.ts +4 -0
- package/packages/ui/src/primitives/Checkbox/Checkbox.variants.ts +34 -0
- package/packages/ui/src/primitives/Checkbox/Checkbox.vue +92 -0
- package/packages/ui/src/primitives/Dialog/Dialog.props.ts +29 -0
- package/packages/ui/src/primitives/Dialog/Dialog.spec.md +52 -0
- package/packages/ui/src/primitives/Dialog/Dialog.types.ts +3 -0
- package/packages/ui/src/primitives/Dialog/Dialog.variants.ts +27 -0
- package/packages/ui/src/primitives/Dialog/Dialog.vue +78 -0
- package/packages/ui/src/primitives/Drawer/Drawer.props.ts +33 -0
- package/packages/ui/src/primitives/Drawer/Drawer.spec.md +50 -0
- package/packages/ui/src/primitives/Drawer/Drawer.types.ts +5 -0
- package/packages/ui/src/primitives/Drawer/Drawer.variants.ts +35 -0
- package/packages/ui/src/primitives/Drawer/Drawer.vue +88 -0
- package/packages/ui/src/primitives/FieldMessage/FieldMessage.props.ts +17 -0
- package/packages/ui/src/primitives/FieldMessage/FieldMessage.spec.md +35 -0
- package/packages/ui/src/primitives/FieldMessage/FieldMessage.types.ts +5 -0
- package/packages/ui/src/primitives/FieldMessage/FieldMessage.variants.ts +14 -0
- package/packages/ui/src/primitives/FieldMessage/FieldMessage.vue +40 -0
- package/packages/ui/src/primitives/FileInput/FileInput.props.ts +41 -0
- package/packages/ui/src/primitives/FileInput/FileInput.types.ts +6 -0
- package/packages/ui/src/primitives/FileInput/FileInput.variants.ts +46 -0
- package/packages/ui/src/primitives/FileInput/FileInput.vue +163 -0
- package/packages/ui/src/primitives/Input/Input.props.ts +29 -0
- package/packages/ui/src/primitives/Input/Input.spec.md +79 -0
- package/packages/ui/src/primitives/Input/Input.types.ts +13 -0
- package/packages/ui/src/primitives/Input/Input.variants.ts +54 -0
- package/packages/ui/src/primitives/Input/Input.vue +99 -0
- package/packages/ui/src/primitives/Label/Label.props.ts +25 -0
- package/packages/ui/src/primitives/Label/Label.spec.md +31 -0
- package/packages/ui/src/primitives/Label/Label.types.ts +3 -0
- package/packages/ui/src/primitives/Label/Label.variants.ts +17 -0
- package/packages/ui/src/primitives/Label/Label.vue +38 -0
- package/packages/ui/src/primitives/Menu/Menu.props.ts +17 -0
- package/packages/ui/src/primitives/Menu/Menu.spec.md +38 -0
- package/packages/ui/src/primitives/Menu/Menu.types.ts +10 -0
- package/packages/ui/src/primitives/Menu/Menu.variants.ts +10 -0
- package/packages/ui/src/primitives/Menu/Menu.vue +57 -0
- package/packages/ui/src/primitives/Popover/Popover.props.ts +25 -0
- package/packages/ui/src/primitives/Popover/Popover.spec.md +49 -0
- package/packages/ui/src/primitives/Popover/Popover.types.ts +3 -0
- package/packages/ui/src/primitives/Popover/Popover.variants.ts +18 -0
- package/packages/ui/src/primitives/Popover/Popover.vue +74 -0
- package/packages/ui/src/primitives/RadioGroup/RadioGroup.props.ts +29 -0
- package/packages/ui/src/primitives/RadioGroup/RadioGroup.spec.md +50 -0
- package/packages/ui/src/primitives/RadioGroup/RadioGroup.types.ts +12 -0
- package/packages/ui/src/primitives/RadioGroup/RadioGroup.variants.ts +48 -0
- package/packages/ui/src/primitives/RadioGroup/RadioGroup.vue +87 -0
- package/packages/ui/src/primitives/Separator/Separator.props.ts +9 -0
- package/packages/ui/src/primitives/Separator/Separator.spec.md +15 -0
- package/packages/ui/src/primitives/Separator/Separator.types.ts +3 -0
- package/packages/ui/src/primitives/Separator/Separator.variants.ts +8 -0
- package/packages/ui/src/primitives/Separator/Separator.vue +23 -0
- package/packages/ui/src/primitives/Skeleton/Skeleton.props.ts +21 -0
- package/packages/ui/src/primitives/Skeleton/Skeleton.spec.md +18 -0
- package/packages/ui/src/primitives/Skeleton/Skeleton.types.ts +5 -0
- package/packages/ui/src/primitives/Skeleton/Skeleton.variants.ts +18 -0
- package/packages/ui/src/primitives/Skeleton/Skeleton.vue +37 -0
- package/packages/ui/src/primitives/Spinner/Spinner.props.ts +13 -0
- package/packages/ui/src/primitives/Spinner/Spinner.spec.md +16 -0
- package/packages/ui/src/primitives/Spinner/Spinner.types.ts +5 -0
- package/packages/ui/src/primitives/Spinner/Spinner.variants.ts +15 -0
- package/packages/ui/src/primitives/Spinner/Spinner.vue +33 -0
- package/packages/ui/src/primitives/SplitButton/SplitButton.vue +108 -0
- package/packages/ui/src/primitives/Switch/Switch.props.ts +21 -0
- package/packages/ui/src/primitives/Switch/Switch.spec.md +49 -0
- package/packages/ui/src/primitives/Switch/Switch.types.ts +3 -0
- package/packages/ui/src/primitives/Switch/Switch.variants.ts +34 -0
- package/packages/ui/src/primitives/Switch/Switch.vue +71 -0
- package/packages/ui/src/primitives/Tabs/Tabs.props.ts +25 -0
- package/packages/ui/src/primitives/Tabs/Tabs.spec.md +48 -0
- package/packages/ui/src/primitives/Tabs/Tabs.types.ts +11 -0
- package/packages/ui/src/primitives/Tabs/Tabs.variants.ts +28 -0
- package/packages/ui/src/primitives/Tabs/Tabs.vue +59 -0
- package/packages/ui/src/primitives/Textarea/Textarea.props.ts +33 -0
- package/packages/ui/src/primitives/Textarea/Textarea.spec.md +59 -0
- package/packages/ui/src/primitives/Textarea/Textarea.types.ts +5 -0
- package/packages/ui/src/primitives/Textarea/Textarea.variants.ts +27 -0
- package/packages/ui/src/primitives/Textarea/Textarea.vue +74 -0
- package/packages/ui/src/primitives/Tooltip/Tooltip.props.ts +21 -0
- package/packages/ui/src/primitives/Tooltip/Tooltip.spec.md +45 -0
- package/packages/ui/src/primitives/Tooltip/Tooltip.types.ts +3 -0
- package/packages/ui/src/primitives/Tooltip/Tooltip.variants.ts +4 -0
- package/packages/ui/src/primitives/Tooltip/Tooltip.vue +31 -0
- package/packages/ui/src/primitives/TreeView/TreeView.types.ts +10 -0
- package/packages/ui/src/primitives/TreeView/TreeView.vue +113 -0
- package/packages/ui/src/primitives/TreeView/TreeViewNode.vue +190 -0
- package/packages/ui/src/primitives/index.ts +29 -0
- package/packages/ui/src/style.css +7 -0
- package/packages/ui/src/style.js +1 -0
- package/packages/ui/src/themes/armour.css +147 -0
- package/packages/ui/src/themes/aurora.css +147 -0
- package/packages/ui/src/themes/citrine-ash.css +147 -0
- package/packages/ui/src/themes/concord.css +147 -0
- package/packages/ui/src/themes/garnet-honey.css +147 -0
- package/packages/ui/src/themes/harbor-rose.css +147 -0
- package/packages/ui/src/themes/ledger.css +147 -0
- package/packages/ui/src/themes/neon-noir.css +74 -0
- package/packages/ui/src/themes/obsidian-iris.css +147 -0
- package/packages/ui/src/themes/pixpax.css +147 -0
- package/packages/ui/src/themes/print.css +147 -0
- package/packages/ui/src/themes/prism.css +147 -0
- package/packages/ui/src/themes/proof.css +145 -0
- package/packages/ui/src/themes/semanticThemeContract.js +2256 -0
- package/packages/ui/src/themes/spruce-ink.css +147 -0
- package/packages/ui/src/themes/sunset.css +147 -0
- package/packages/ui/tailwind.config.js +64 -0
- package/packages/ui/vite.config.js +35 -0
- package/packages/ui/vite.config.js.timestamp-1780697224943-89fbc929987bc.mjs +38 -0
- package/packages/utils/CHANGELOG.md +111 -0
- package/packages/utils/README.md +3 -0
- package/packages/utils/package.json +46 -0
- package/packages/utils/src/index.test.js +39 -0
- package/packages/utils/src/index.ts +289 -0
- package/packages/utils/tsconfig.build.json +12 -0
- package/packages/utils/vite.config.js +28 -0
- package/pnpm-workspace.yaml +8 -0
- package/scripts/vite/package-lib-config.ts +59 -0
- package/tsconfig.json +24 -0
- package/tsconfig.node.json +9 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# `@ternent/concord` Specification
|
|
2
|
+
|
|
3
|
+
## 1. Purpose
|
|
4
|
+
|
|
5
|
+
`@ternent/concord` is the developer-facing runtime for building non-custodial applications on top of `@ternent/ledger`.
|
|
6
|
+
|
|
7
|
+
Concord is command-first, but replay is the primary abstraction.
|
|
8
|
+
|
|
9
|
+
It exists to make this normal:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
const app = await createConcordApp({
|
|
13
|
+
identity,
|
|
14
|
+
storage,
|
|
15
|
+
plugins: [createTodoPlugin()],
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
await app.load();
|
|
19
|
+
|
|
20
|
+
await app.command("todo.create-item", {
|
|
21
|
+
id: crypto.randomUUID(),
|
|
22
|
+
title: "Buy milk",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
await app.command("todo.rename-item", {
|
|
26
|
+
id: "todo_123",
|
|
27
|
+
title: "Buy oat milk",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
await app.commit({
|
|
31
|
+
metadata: {
|
|
32
|
+
message: "Create and refine first todo",
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Commands stage domain meaning. Replay plugins consume ordered replay entries. Commits author signed history boundaries.
|
|
38
|
+
|
|
39
|
+
## 2. Layering
|
|
40
|
+
|
|
41
|
+
- `@ternent/concord-protocol` provides deterministic protocol primitives
|
|
42
|
+
- `@ternent/ledger` owns append-only truth, signed commits, replay, and verification
|
|
43
|
+
- `@ternent/concord` owns command dispatch, replay plugin hosting, and runtime composition
|
|
44
|
+
- framework adapters belong above Concord
|
|
45
|
+
|
|
46
|
+
Concord must never reimplement ledger truth mechanics.
|
|
47
|
+
|
|
48
|
+
## 3. Core Model
|
|
49
|
+
|
|
50
|
+
### 3.1 Truth vs runtime state
|
|
51
|
+
|
|
52
|
+
- entries are units of meaning
|
|
53
|
+
- signed commits are the primary authored integrity boundary
|
|
54
|
+
- replay-derived state is derived from replay
|
|
55
|
+
- replay plugins are the only replay consumer type
|
|
56
|
+
- storage is persistence only
|
|
57
|
+
|
|
58
|
+
### 3.2 Command and commit lifecycle
|
|
59
|
+
|
|
60
|
+
The normal Concord write lifecycle is:
|
|
61
|
+
|
|
62
|
+
1. dispatch one or more commands
|
|
63
|
+
2. stage one or more ledger entries
|
|
64
|
+
3. replay committed truth plus staged truth into replay-derived runtime state
|
|
65
|
+
4. explicitly commit staged entries into a signed commit
|
|
66
|
+
5. replay the updated committed history
|
|
67
|
+
|
|
68
|
+
Concord may support optional auto-commit hooks, but explicit commits are the default and primary model.
|
|
69
|
+
|
|
70
|
+
## 4. Public API
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
type ConcordApp = {
|
|
74
|
+
create(params?: ConcordCreateParams): Promise<void>;
|
|
75
|
+
load(): Promise<void>;
|
|
76
|
+
|
|
77
|
+
command<TInput = unknown>(type: string, input: TInput): Promise<ConcordCommandResult>;
|
|
78
|
+
|
|
79
|
+
commit(input?: ConcordCommitInput): Promise<ConcordCommitResult>;
|
|
80
|
+
|
|
81
|
+
replay(options?: ConcordReplayOptions): Promise<void>;
|
|
82
|
+
recompute(): Promise<void>;
|
|
83
|
+
|
|
84
|
+
verify(): Promise<LedgerVerificationResult>;
|
|
85
|
+
|
|
86
|
+
exportLedger(): Promise<LedgerContainer>;
|
|
87
|
+
importLedger(container: LedgerContainer): Promise<void>;
|
|
88
|
+
|
|
89
|
+
getState(): Readonly<ConcordState>;
|
|
90
|
+
getReplayState<T = unknown>(pluginId: string): T;
|
|
91
|
+
|
|
92
|
+
subscribe(listener: (state: Readonly<ConcordState>) => void): () => void;
|
|
93
|
+
destroy(): Promise<void>;
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`ConcordAppOptions` uses:
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
type ConcordAppOptions = {
|
|
101
|
+
identity: SerializedIdentity;
|
|
102
|
+
storage?: LedgerStorageAdapter;
|
|
103
|
+
plugins: ConcordReplayPlugin[];
|
|
104
|
+
now?: () => string;
|
|
105
|
+
protocol?: LedgerProtocolContract;
|
|
106
|
+
seal?: LedgerSealContract;
|
|
107
|
+
armour?: LedgerArmourContract;
|
|
108
|
+
ledger?: LedgerInstance<LedgerReplayEntry[]>;
|
|
109
|
+
policy?: ConcordRuntimePolicy;
|
|
110
|
+
};
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Rules:
|
|
114
|
+
|
|
115
|
+
- `storage` is optional
|
|
116
|
+
- a supplied ledger must replay `LedgerReplayEntry[]`
|
|
117
|
+
- the app passes one high-level identity object
|
|
118
|
+
- Concord derives author, signer, and decrypt capability internally when it creates the ledger
|
|
119
|
+
|
|
120
|
+
## 5. Identity Model
|
|
121
|
+
|
|
122
|
+
```ts
|
|
123
|
+
type SerializedIdentity = {
|
|
124
|
+
keyId: string;
|
|
125
|
+
// ...
|
|
126
|
+
};
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Rules:
|
|
130
|
+
|
|
131
|
+
- this is the public identity shape the app passes to Concord
|
|
132
|
+
- Concord internally adapts it into ledger signer / author / decryptor wiring
|
|
133
|
+
- command handlers receive this same high-level identity unchanged
|
|
134
|
+
- replay plugins do not receive ledger adaptation details
|
|
135
|
+
|
|
136
|
+
## 6. State Model
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
type ConcordState = {
|
|
140
|
+
ready: boolean;
|
|
141
|
+
integrityValid: boolean;
|
|
142
|
+
stagedCount: number;
|
|
143
|
+
replay: Record<string, unknown>;
|
|
144
|
+
verification: LedgerVerificationResult | null;
|
|
145
|
+
};
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Rules:
|
|
149
|
+
|
|
150
|
+
- `replay` is replay-derived runtime state
|
|
151
|
+
- `integrityValid` indicates whether the currently loaded committed history passed strict ledger verification
|
|
152
|
+
- `stagedCount` exposes local working-state depth without leaking raw ledger internals as the primary surface
|
|
153
|
+
- verification applies to the ledger artifact and current staged state, not to replay-derived state as authority
|
|
154
|
+
- `ready` means the app has a trustworthy projected runtime state available for normal use
|
|
155
|
+
|
|
156
|
+
## 7. Replay Plugin Model
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
type ConcordReplayPlugin<PState = unknown> = {
|
|
160
|
+
id: string;
|
|
161
|
+
initialState?: () => PState;
|
|
162
|
+
commands?: Record<string, ConcordCommandHandler>;
|
|
163
|
+
reset?: (ctx: ConcordReplayContext<PState>) => Promise<void> | void;
|
|
164
|
+
beginReplay?: (ctx: ConcordReplayContext<PState>) => Promise<void> | void;
|
|
165
|
+
applyEntry?: (
|
|
166
|
+
entry: LedgerReplayEntry,
|
|
167
|
+
ctx: ConcordReplayContext<PState>,
|
|
168
|
+
) => Promise<void> | void;
|
|
169
|
+
endReplay?: (ctx: ConcordReplayContext<PState>) => Promise<void> | void;
|
|
170
|
+
destroy?: () => Promise<void> | void;
|
|
171
|
+
selectors?: Record<string, (state: PState) => unknown>;
|
|
172
|
+
};
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Replay context:
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
type ConcordReplayContext<PState = unknown> = {
|
|
179
|
+
pluginId: string;
|
|
180
|
+
decryptAvailable: boolean;
|
|
181
|
+
replay: {
|
|
182
|
+
phase: "reset" | "beginReplay" | "applyEntry" | "endReplay";
|
|
183
|
+
entryIndex?: number;
|
|
184
|
+
entryCount: number;
|
|
185
|
+
fromEntryId?: string;
|
|
186
|
+
toEntryId?: string;
|
|
187
|
+
isPartial: boolean;
|
|
188
|
+
};
|
|
189
|
+
getState(): PState;
|
|
190
|
+
setState(next: PState | ((prev: PState) => PState)): void;
|
|
191
|
+
};
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Rules:
|
|
195
|
+
|
|
196
|
+
- replay plugins are the only replay consumer type
|
|
197
|
+
- commands return ledger append inputs
|
|
198
|
+
- commands stage entries; they do not implicitly define commit boundaries
|
|
199
|
+
- replay plugins are isolated by plugin id
|
|
200
|
+
- replay plugins can read and write only their own replay state during replay
|
|
201
|
+
- Concord does not support cross-plugin replay reads during a replay pass
|
|
202
|
+
|
|
203
|
+
`reset` has strict semantics:
|
|
204
|
+
|
|
205
|
+
- `reset` prepares plugin-local replay workspace for a new replay pass
|
|
206
|
+
- `reset` does not imply clearing previously published external surfaces
|
|
207
|
+
- external atomic swap, if needed, belongs to the plugin and usually happens in `endReplay`
|
|
208
|
+
|
|
209
|
+
`selectors` are passive metadata only. Concord does not add selector runtime behavior.
|
|
210
|
+
|
|
211
|
+
## 8. Replay Rules
|
|
212
|
+
|
|
213
|
+
Concord rebuilds runtime state with one replay pipeline:
|
|
214
|
+
|
|
215
|
+
1. verify committed history before trusted rebuild
|
|
216
|
+
2. ask Ledger for ordered replay entries
|
|
217
|
+
3. create isolated draft replay state for all plugins
|
|
218
|
+
4. run `reset`
|
|
219
|
+
5. run `beginReplay`
|
|
220
|
+
6. run `applyEntry` for each ordered entry
|
|
221
|
+
7. run `endReplay`
|
|
222
|
+
8. publish Concord state once after full success
|
|
223
|
+
|
|
224
|
+
Failure rules:
|
|
225
|
+
|
|
226
|
+
- abort immediately on any replay hook failure
|
|
227
|
+
- do not publish partial Concord state
|
|
228
|
+
- do not mutate the last-known-good published Concord state
|
|
229
|
+
- do not attempt cleanup `reset` or rollback magic
|
|
230
|
+
|
|
231
|
+
Atomicity rule:
|
|
232
|
+
|
|
233
|
+
- Concord guarantees atomicity only at the published Concord state boundary
|
|
234
|
+
- external surfaces owned by plugins must handle their own buffered publish / swap if they need atomic updates
|
|
235
|
+
|
|
236
|
+
## 9. Partial Replay
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
type ConcordReplayOptions = {
|
|
240
|
+
verify?: boolean;
|
|
241
|
+
decrypt?: boolean;
|
|
242
|
+
fromEntryId?: string;
|
|
243
|
+
toEntryId?: string;
|
|
244
|
+
};
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Rules:
|
|
248
|
+
|
|
249
|
+
- replay of any ordered slice is deterministic
|
|
250
|
+
- replay metadata is range-aware so Concord stays compatible with timeline scrubbing and replay-slider UX
|
|
251
|
+
- authoritative full-state reconstruction still requires replay from genesis or a valid checkpoint
|
|
252
|
+
|
|
253
|
+
That distinction is important:
|
|
254
|
+
|
|
255
|
+
- deterministic slice replay is supported now
|
|
256
|
+
- authoritative full-state reconstruction from a non-zero start requires a valid checkpoint layer that Concord does not yet provide
|
|
257
|
+
|
|
258
|
+
## 10. Runtime Rules
|
|
259
|
+
|
|
260
|
+
- Concord defaults to `autoCommit: false`
|
|
261
|
+
- `command()` stages entries and rebuilds local replay-derived state from committed plus staged replay
|
|
262
|
+
- `commit()` creates a signed commit via Ledger and clears staged entries only after successful commit creation
|
|
263
|
+
- `verify()` validates the ledger artifact and current staged state; it does not itself replay
|
|
264
|
+
- `exportLedger()` exposes committed truth only
|
|
265
|
+
- staged truth remains visible through replayed runtime state until explicitly committed or cleared below Concord
|
|
266
|
+
|
|
267
|
+
Concord treats committed history as atomic truth.
|
|
268
|
+
If any committed byte in reachable history is invalid, Concord must not present replay-derived runtime state as trustworthy.
|
|
269
|
+
|
|
270
|
+
That means:
|
|
271
|
+
|
|
272
|
+
- `load()` and `importLedger()` may still succeed for diagnostic inspection
|
|
273
|
+
- invalid committed history forces `ready: false`
|
|
274
|
+
- invalid committed history forces `integrityValid: false`
|
|
275
|
+
- commands and commits are blocked until trustworthy runtime state exists again
|
|
276
|
+
|
|
277
|
+
## 11. Acceptance Criteria
|
|
278
|
+
|
|
279
|
+
Concord is correct when:
|
|
280
|
+
|
|
281
|
+
- multiple commands can stage multiple entries before one explicit commit
|
|
282
|
+
- staged state is visible through replay before commit
|
|
283
|
+
- committed history is advanced only by explicit commit unless auto-commit is intentionally configured
|
|
284
|
+
- exported ledgers show signed commit records as the authored integrity boundary
|
|
285
|
+
- replay plugins are the only replay consumer type
|
|
286
|
+
- docs and examples teach `command -> command -> commit`, not `command = commit`
|
|
287
|
+
- docs clearly distinguish deterministic slice replay from authoritative full-state reconstruction
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ternent/concord",
|
|
3
|
+
"version": "0.2.9",
|
|
4
|
+
"description": "Command-driven developer runtime for building non-custodial apps on @ternent/ledger",
|
|
5
|
+
"license": "ISC",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"README.md",
|
|
9
|
+
"SPEC.md"
|
|
10
|
+
],
|
|
11
|
+
"type": "module",
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"main": "dist/index.js",
|
|
14
|
+
"module": "dist/index.js",
|
|
15
|
+
"types": "dist/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.js",
|
|
20
|
+
"default": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./browser": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/browser.js",
|
|
25
|
+
"default": "./dist/browser.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"dev": "vite build --watch",
|
|
33
|
+
"build:browser": "pnpm --filter @ternent/ledger build && vite build -c vite.browser.config.ts",
|
|
34
|
+
"build": "pnpm --filter @ternent/ledger build && vite build && vite build -c vite.browser.config.ts",
|
|
35
|
+
"test": "pnpm run build && vitest run"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@ternent/ledger": "workspace:*"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@ternent/armour": "workspace:*",
|
|
42
|
+
"@ternent/identity": "workspace:*",
|
|
43
|
+
"@ternent/rage": "workspace:*",
|
|
44
|
+
"@ternent/seal-cli": "workspace:*",
|
|
45
|
+
"@types/node": "^24.3.0",
|
|
46
|
+
"typescript": "^5.6.3",
|
|
47
|
+
"vite": "^4.5.3",
|
|
48
|
+
"vite-plugin-dts": "^1.7.3",
|
|
49
|
+
"vitest": "^1.6.0"
|
|
50
|
+
}
|
|
51
|
+
}
|