@hasna/economy 0.3.28 → 0.5.0
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/CHANGELOG.md +119 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +18 -22
- package/SECURITY.md +1 -1
- package/dist/chunks/agent-registry-store-tpnhx3wj.js +39 -0
- package/dist/chunks/billing-bkpxy4kv.js +13 -0
- package/dist/chunks/config-j9mv3ehk.js +15 -0
- package/dist/chunks/index-2hwzmfgv.js +3407 -0
- package/dist/chunks/index-axh32d30.js +1313 -0
- package/dist/chunks/index-emvs5ph2.js +2085 -0
- package/dist/chunks/index-ez9thsr7.js +3440 -0
- package/dist/chunks/index-hesxq90g.js +62 -0
- package/dist/chunks/index-k540hfww.js +258 -0
- package/dist/chunks/index-kgy9b6bf.js +451 -0
- package/dist/chunks/index-kn5572kd.js +124 -0
- package/dist/chunks/index-p35cyhc4.js +4 -0
- package/dist/chunks/index-w3bvv0ns.js +26 -0
- package/dist/chunks/index-zpvea08j.js +3372 -0
- package/dist/chunks/menubar-6xtkt17h.js +296 -0
- package/dist/chunks/open-projects-6z4pq6mx.js +39 -0
- package/dist/chunks/pricing-f80p81gr.js +29 -0
- package/dist/chunks/pricing-vf2pycmh.js +30 -0
- package/dist/chunks/pricing-y21mcjsa.js +30 -0
- package/dist/chunks/serve-0k69e4h9.js +4655 -0
- package/dist/chunks/sqlite-store-501f32ts.js +258 -0
- package/dist/chunks/sqlite-store-fq4natnf.js +256 -0
- package/dist/chunks/sqlite-store-st99garx.js +258 -0
- package/dist/chunks/third-party-sqlite-5e85fxa2.js +11 -0
- package/dist/chunks/tui-7f8f951w.js +22 -0
- package/dist/chunks/watch-mm1j39vy.js +196 -0
- package/dist/chunks/webhooks-k4fh2t9c.js +109 -0
- package/dist/cli/commands/brief.d.ts.map +1 -1
- package/dist/cli/commands/extras.d.ts.map +1 -1
- package/dist/cli/commands/journal.d.ts +3 -0
- package/dist/cli/commands/journal.d.ts.map +1 -0
- package/dist/cli/commands/menubar.d.ts +97 -4
- package/dist/cli/commands/menubar.d.ts.map +1 -1
- package/dist/cli/commands/tui.d.ts +1 -1
- package/dist/cli/commands/tui.d.ts.map +1 -1
- package/dist/cli/commands/watch.d.ts.map +1 -1
- package/dist/cli/index.js +1524 -9998
- package/dist/db/cloud.d.ts +18 -12
- package/dist/db/cloud.d.ts.map +1 -1
- package/dist/db/database.d.ts +33 -12
- package/dist/db/database.d.ts.map +1 -1
- package/dist/db/ingest-concurrency-worker.d.ts +2 -0
- package/dist/db/ingest-concurrency-worker.d.ts.map +1 -0
- package/dist/db/ingest-errors.d.ts +9 -0
- package/dist/db/ingest-errors.d.ts.map +1 -0
- package/dist/db/ingest-schema.d.ts +3 -0
- package/dist/db/ingest-schema.d.ts.map +1 -0
- package/dist/db/ingest-specs.d.ts +8 -0
- package/dist/db/ingest-specs.d.ts.map +1 -0
- package/dist/db/ingest-test-contract.d.ts +3 -0
- package/dist/db/ingest-test-contract.d.ts.map +1 -0
- package/dist/db/ingest-validation.d.ts +12 -0
- package/dist/db/ingest-validation.d.ts.map +1 -0
- package/dist/db/ingest.d.ts +27 -0
- package/dist/db/ingest.d.ts.map +1 -0
- package/dist/db/legacy-schema.d.ts +7 -0
- package/dist/db/legacy-schema.d.ts.map +1 -0
- package/dist/db/observation-contract.d.ts +3 -0
- package/dist/db/observation-contract.d.ts.map +1 -0
- package/dist/db/observation-provenance.d.ts +23 -0
- package/dist/db/observation-provenance.d.ts.map +1 -0
- package/dist/db/observation-schema.d.ts +24 -0
- package/dist/db/observation-schema.d.ts.map +1 -0
- package/dist/db/pg-connection.d.ts +10 -0
- package/dist/db/pg-connection.d.ts.map +1 -0
- package/dist/db/pg-migrate.d.ts +4 -9
- package/dist/db/pg-migrate.d.ts.map +1 -1
- package/dist/db/pg-migrations.d.ts.map +1 -1
- package/dist/db/pg-protocol.d.ts +28 -0
- package/dist/db/pg-protocol.d.ts.map +1 -0
- package/dist/db/sqlite-store.d.ts +4 -0
- package/dist/db/sqlite-store.d.ts.map +1 -0
- package/dist/db/sync-pg.d.ts +17 -21
- package/dist/db/sync-pg.d.ts.map +1 -1
- package/dist/db/third-party-sqlite.d.ts +10 -0
- package/dist/db/third-party-sqlite.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1281 -2405
- package/dist/ingest/claude-quota.d.ts.map +1 -1
- package/dist/ingest/claude.d.ts.map +1 -1
- package/dist/ingest/codex-quota.d.ts.map +1 -1
- package/dist/ingest/codex.d.ts +25 -0
- package/dist/ingest/codex.d.ts.map +1 -1
- package/dist/ingest/collection-outcome.d.ts +17 -0
- package/dist/ingest/collection-outcome.d.ts.map +1 -0
- package/dist/ingest/cursor.d.ts.map +1 -1
- package/dist/ingest/gemini.d.ts.map +1 -1
- package/dist/ingest/hermes.d.ts +1 -1
- package/dist/ingest/hermes.d.ts.map +1 -1
- package/dist/ingest/loops.d.ts +9 -0
- package/dist/ingest/loops.d.ts.map +1 -1
- package/dist/ingest/opencode.d.ts +1 -1
- package/dist/ingest/opencode.d.ts.map +1 -1
- package/dist/ingest/pi.d.ts +1 -1
- package/dist/ingest/pi.d.ts.map +1 -1
- package/dist/ingest/quota-observation.d.ts +16 -0
- package/dist/ingest/quota-observation.d.ts.map +1 -0
- package/dist/ingest/source-time.d.ts +4 -0
- package/dist/ingest/source-time.d.ts.map +1 -0
- package/dist/lib/accounts-store.d.ts +109 -0
- package/dist/lib/accounts-store.d.ts.map +1 -0
- package/dist/lib/accounts.d.ts +2 -1
- package/dist/lib/accounts.d.ts.map +1 -1
- package/dist/lib/analytics.d.ts.map +1 -1
- package/dist/lib/api-display-url.d.ts +19 -0
- package/dist/lib/api-display-url.d.ts.map +1 -0
- package/dist/lib/autosync-gate.d.ts +22 -0
- package/dist/lib/autosync-gate.d.ts.map +1 -0
- package/dist/lib/billing-diff.d.ts +18 -40
- package/dist/lib/billing-diff.d.ts.map +1 -1
- package/dist/lib/brief.d.ts +2 -0
- package/dist/lib/brief.d.ts.map +1 -1
- package/dist/lib/budget-decimal.d.ts +14 -0
- package/dist/lib/budget-decimal.d.ts.map +1 -0
- package/dist/lib/cloud-ingest.d.ts +30 -1
- package/dist/lib/cloud-ingest.d.ts.map +1 -1
- package/dist/lib/cloud-storage.d.ts +166 -10
- package/dist/lib/cloud-storage.d.ts.map +1 -1
- package/dist/lib/gatherer.d.ts.map +1 -1
- package/dist/lib/ingest-batches.d.ts +21 -0
- package/dist/lib/ingest-batches.d.ts.map +1 -0
- package/dist/lib/ingest-journal-client.d.ts +37 -0
- package/dist/lib/ingest-journal-client.d.ts.map +1 -0
- package/dist/lib/ingest-journal-lock.d.ts +5 -0
- package/dist/lib/ingest-journal-lock.d.ts.map +1 -0
- package/dist/lib/ingest-journal-maintenance.d.ts +92 -0
- package/dist/lib/ingest-journal-maintenance.d.ts.map +1 -0
- package/dist/lib/ingest-journal-operation.d.ts +55 -0
- package/dist/lib/ingest-journal-operation.d.ts.map +1 -0
- package/dist/lib/ingest-journal.d.ts +73 -0
- package/dist/lib/ingest-journal.d.ts.map +1 -0
- package/dist/lib/money-display.d.ts +13 -0
- package/dist/lib/money-display.d.ts.map +1 -0
- package/dist/lib/periods.d.ts +12 -0
- package/dist/lib/periods.d.ts.map +1 -1
- package/dist/lib/pricing.d.ts +14 -0
- package/dist/lib/pricing.d.ts.map +1 -1
- package/dist/lib/savings.d.ts +64 -7
- package/dist/lib/savings.d.ts.map +1 -1
- package/dist/lib/serve-auth.d.ts.map +1 -1
- package/dist/lib/store/index.d.ts +29 -22
- package/dist/lib/store/index.d.ts.map +1 -1
- package/dist/lib/summary-contract.d.ts +32 -0
- package/dist/lib/summary-contract.d.ts.map +1 -0
- package/dist/lib/summary-test-contract.d.ts +3 -0
- package/dist/lib/summary-test-contract.d.ts.map +1 -0
- package/dist/lib/sync-all.d.ts +4 -0
- package/dist/lib/sync-all.d.ts.map +1 -1
- package/dist/lib/sync-maintenance.d.ts.map +1 -1
- package/dist/lib/sync-report.d.ts +4 -0
- package/dist/lib/sync-report.d.ts.map +1 -0
- package/dist/lib/test-keychain-fixture.d.ts +9 -0
- package/dist/lib/test-keychain-fixture.d.ts.map +1 -0
- package/dist/mcp/agent-registry-store.d.ts +30 -0
- package/dist/mcp/agent-registry-store.d.ts.map +1 -0
- package/dist/mcp/agent-registry.d.ts +78 -0
- package/dist/mcp/agent-registry.d.ts.map +1 -0
- package/dist/mcp/harness.d.ts +26 -0
- package/dist/mcp/harness.d.ts.map +1 -0
- package/dist/mcp/index.js +3219 -3357
- package/dist/mcp/ingest-journal-tool.d.ts +2 -0
- package/dist/mcp/ingest-journal-tool.d.ts.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/otel/index.js +2197 -121
- package/dist/server/human-auth.d.ts +20 -0
- package/dist/server/human-auth.d.ts.map +1 -0
- package/dist/server/index.js +10477 -6378
- package/dist/server/legacy-inventory.d.ts +52 -0
- package/dist/server/legacy-inventory.d.ts.map +1 -0
- package/dist/server/legacy-operations.d.ts +64 -0
- package/dist/server/legacy-operations.d.ts.map +1 -0
- package/dist/server/legacy-plan.d.ts +55 -0
- package/dist/server/legacy-plan.d.ts.map +1 -0
- package/dist/server/legacy-preservation.d.ts +58 -0
- package/dist/server/legacy-preservation.d.ts.map +1 -0
- package/dist/server/pg-sync-worker.js +195 -21
- package/dist/server/serve.d.ts +20 -18
- package/dist/server/serve.d.ts.map +1 -1
- package/dist/server/service-admission.d.ts +10 -0
- package/dist/server/service-admission.d.ts.map +1 -0
- package/dist/server/service-dispatcher.d.ts +45 -0
- package/dist/server/service-dispatcher.d.ts.map +1 -0
- package/dist/server/service-operations.d.ts +5 -0
- package/dist/server/service-operations.d.ts.map +1 -0
- package/dist/server/service-protocol.d.ts +50 -0
- package/dist/server/service-protocol.d.ts.map +1 -0
- package/dist/server/service-worker.d.ts +2 -0
- package/dist/server/service-worker.d.ts.map +1 -0
- package/dist/server/service-worker.js +8029 -0
- package/dist/types/index.d.ts +66 -0
- package/dist/types/index.d.ts.map +1 -1
- package/docs/README.md +1 -1
- package/docs/cli.md +2 -3
- package/docs/configuration.md +25 -12
- package/docs/cost-reporting.md +49 -0
- package/docs/historical-data-reconciliation.md +203 -0
- package/docs/ingest-journal.md +108 -0
- package/docs/ingestion.md +61 -5
- package/docs/mcp.md +5 -3
- package/docs/native-budget-save.md +84 -0
- package/docs/native-human-auth.md +102 -0
- package/docs/otel.md +8 -2
- package/docs/rest-api.md +4 -4
- package/package.json +17 -20
- package/postinstall.js +52 -1
- package/dashboard/README.md +0 -26
- package/dist/cli/brains.d.ts +0 -3
- package/dist/cli/brains.d.ts.map +0 -1
- package/dist/lib/test-hermetic-accounts.d.ts +0 -6
- package/dist/lib/test-hermetic-accounts.d.ts.map +0 -1
package/dist/types/index.d.ts
CHANGED
|
@@ -78,8 +78,11 @@ export interface Budget {
|
|
|
78
78
|
alert_at_percent: number;
|
|
79
79
|
created_at: string;
|
|
80
80
|
updated_at: string;
|
|
81
|
+
/** Omitted by legacy callers; server responses always identify the metric. */
|
|
82
|
+
metric?: 'legacy_request_cost_usd' | 'metered_api_usd';
|
|
81
83
|
}
|
|
82
84
|
export interface BudgetStatus extends Budget {
|
|
85
|
+
period_bounds: import('../lib/periods.js').CalendarPeriodBounds;
|
|
83
86
|
current_spend_usd: number;
|
|
84
87
|
percent_used: number;
|
|
85
88
|
is_over_limit: boolean;
|
|
@@ -91,12 +94,41 @@ export interface IngestState {
|
|
|
91
94
|
value: string;
|
|
92
95
|
}
|
|
93
96
|
export interface CostSummary {
|
|
97
|
+
/** Compatibility subtotal of known stored values, including separately reported session-only values. */
|
|
94
98
|
total_usd: number;
|
|
99
|
+
complete_total_usd: number | null;
|
|
100
|
+
basis: 'known_usage_value_subtotal';
|
|
101
|
+
completeness: 'complete' | 'partial' | 'unavailable' | 'no_records';
|
|
102
|
+
coverage_scope: 'selected_stored_records';
|
|
103
|
+
source_coverage: 'not_established';
|
|
104
|
+
period_bounds: import('../lib/periods.js').CalendarPeriodBounds;
|
|
105
|
+
request_rows: number;
|
|
106
|
+
recorded_metered_api_usd: number;
|
|
107
|
+
estimated_usage_value_usd: number;
|
|
108
|
+
subscription_included_value_usd: number;
|
|
109
|
+
/** Lifetime totals of overlapping sessions without request rows; not allocated to this period. */
|
|
110
|
+
session_only_value_usd: number;
|
|
111
|
+
unknown_price_requests: number;
|
|
112
|
+
unknown_basis_requests: number;
|
|
113
|
+
session_only_sessions: number;
|
|
95
114
|
sessions: number;
|
|
96
115
|
requests: number;
|
|
97
116
|
tokens: number;
|
|
98
117
|
period: Period;
|
|
99
118
|
}
|
|
119
|
+
export interface BillingSummary {
|
|
120
|
+
/** Compatibility subtotal of the selected imported provider rows, never a complete invoice claim. */
|
|
121
|
+
total_usd: number;
|
|
122
|
+
recorded_total_usd: number | null;
|
|
123
|
+
complete_total_usd: null;
|
|
124
|
+
basis: 'recorded_provider_rows_subtotal';
|
|
125
|
+
status: 'observed' | 'no_records';
|
|
126
|
+
coverage_scope: 'selected_stored_records';
|
|
127
|
+
source_coverage: 'not_established';
|
|
128
|
+
period_bounds: import('../lib/periods.js').CalendarPeriodBounds;
|
|
129
|
+
record_count: number;
|
|
130
|
+
by_provider: Record<string, number>;
|
|
131
|
+
}
|
|
100
132
|
export interface ZeroCostModelBreakdown {
|
|
101
133
|
agent: import('../lib/agents.js').Agent;
|
|
102
134
|
model: string;
|
|
@@ -194,6 +226,14 @@ export interface SyncOptions {
|
|
|
194
226
|
dedupe?: boolean;
|
|
195
227
|
/** Claude/Takumi JSONL root override (tests). */
|
|
196
228
|
projectsDir?: string;
|
|
229
|
+
/**
|
|
230
|
+
* Refuse collectors that read ANOTHER Hasna app's on-box SQLite (today: the
|
|
231
|
+
* `loops` collector, which reads `~/.hasna/loops/loops.db`). Set by the
|
|
232
|
+
* hosted push (`syncAllToCloud`): a client with a hosted credential never
|
|
233
|
+
* takes another app's local store as fleet truth — that data must come from
|
|
234
|
+
* the loops API. PORT-TO-API, tracked for W13 (fleet-alignment ruling d).
|
|
235
|
+
*/
|
|
236
|
+
noCrossAppLocalReads?: boolean;
|
|
197
237
|
}
|
|
198
238
|
export interface SessionFilter {
|
|
199
239
|
agent?: import('../lib/agents.js').Agent;
|
|
@@ -217,6 +257,11 @@ export interface Subscription {
|
|
|
217
257
|
active: number;
|
|
218
258
|
created_at: string;
|
|
219
259
|
updated_at: string;
|
|
260
|
+
account_key?: string;
|
|
261
|
+
observed_station?: string | null;
|
|
262
|
+
observed_at?: string | null;
|
|
263
|
+
fee_basis?: import('../db/observation-provenance.js').AmountBasis;
|
|
264
|
+
included_basis?: import('../db/observation-provenance.js').AmountBasis;
|
|
220
265
|
}
|
|
221
266
|
export interface UsageSnapshot {
|
|
222
267
|
id: string;
|
|
@@ -227,6 +272,27 @@ export interface UsageSnapshot {
|
|
|
227
272
|
unit: string;
|
|
228
273
|
machine_id: string;
|
|
229
274
|
updated_at: string;
|
|
275
|
+
provider?: string;
|
|
276
|
+
account_key?: string;
|
|
277
|
+
observed_at?: string | null;
|
|
278
|
+
source_timestamp?: string | null;
|
|
279
|
+
window_start?: string | null;
|
|
280
|
+
window_end?: string | null;
|
|
281
|
+
reset_at?: string | null;
|
|
282
|
+
window_seconds?: number | null;
|
|
283
|
+
value_kind?: import('../db/observation-provenance.js').ValueKind;
|
|
284
|
+
}
|
|
285
|
+
export interface ScanReceipt {
|
|
286
|
+
id: string;
|
|
287
|
+
machine_id: string;
|
|
288
|
+
source: string;
|
|
289
|
+
attempted_at: string;
|
|
290
|
+
completed_at: string;
|
|
291
|
+
status: 'success' | 'unchanged' | 'missing' | 'unsupported' | 'failed';
|
|
292
|
+
latest_event_at: string | null;
|
|
293
|
+
parser_version: string;
|
|
294
|
+
error_code: string | null;
|
|
295
|
+
updated_at?: string;
|
|
230
296
|
}
|
|
231
297
|
export interface MachineRegistry {
|
|
232
298
|
machine_id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"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"}
|
package/docs/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Economy documentation
|
|
2
2
|
|
|
3
|
-
Economy can run as an on-machine SQLite application or as a client of a shared
|
|
3
|
+
Economy can run as an on-machine SQLite application or as a client of a shared HTTP service. These guides describe the current command and network surfaces:
|
|
4
4
|
|
|
5
5
|
- [CLI reference](cli.md) — the `economy` command and the four installed binaries.
|
|
6
6
|
- [Ingestion](ingestion.md) — supported sources, default paths, sync behavior, billing, and account attribution.
|
package/docs/cli.md
CHANGED
|
@@ -6,7 +6,7 @@ Installing `@hasna/economy` provides four binaries:
|
|
|
6
6
|
| --- | --- |
|
|
7
7
|
| `economy` | Ingest, query, and manage Economy data. |
|
|
8
8
|
| `economy-mcp` | Run the MCP server over stdio or Streamable HTTP. |
|
|
9
|
-
| `economy-serve` | Serve the REST API
|
|
9
|
+
| `economy-serve` | Serve the REST API, or migrate the server database. |
|
|
10
10
|
| `economy-otel` | Ingest OTLP/HTTP metrics or simplified cost events into local SQLite. |
|
|
11
11
|
|
|
12
12
|
Use `<binary> --help` and `economy <command> --help` for the exact help emitted by the installed version.
|
|
@@ -32,6 +32,7 @@ The supported coding-agent values are `claude`, `takumi`, `codex`, `gemini`, `op
|
|
|
32
32
|
| `economy watch` | Poll recent costs, or use `--daemon` to sync watched local paths. Also accepts `--interval`, `--agent`, and macOS `--notify`. In cloud mode it streams the API and does not ingest local files. |
|
|
33
33
|
| `economy status` | Print one-line spend, fleet, storage, top-agent, and available quota status. |
|
|
34
34
|
| `economy doctor` | Check source paths/token availability, storage mode, pricing gaps, deduplication, and billing drift. |
|
|
35
|
+
| `economy transport` | Report the resolved client transport and credential SOURCE (never the key): the `/v1` authority, the URL/key source names, and the credential tier from the `@hasna/contracts` chain; `--json` for the full report. Exits 0 even when unconfigured — the refusal is the report. |
|
|
35
36
|
| `economy init` | Print first-run local and cloud-client setup hints. |
|
|
36
37
|
|
|
37
38
|
Human output for high-cardinality commands is intentionally capped. Use the command's `--json`, `--verbose`, or `--limit` option when available. JSON output is complete; `--verbose` has command-specific semantics, so consult `--help`.
|
|
@@ -67,11 +68,9 @@ Human output for high-cardinality commands is intentionally capped. Use the comm
|
|
|
67
68
|
| Command | Behavior |
|
|
68
69
|
| --- | --- |
|
|
69
70
|
| `economy serve --port <port>` | Start the REST API in-process. Equivalent server controls are documented under [`economy-serve`](configuration.md#rest-server). |
|
|
70
|
-
| `economy dashboard --port <port>` | Start the server when necessary and open the dashboard URL. |
|
|
71
71
|
| `economy mcp` | Print Claude Code, Codex, and Gemini MCP configuration; select one or use `--all`. |
|
|
72
72
|
| `economy completion <shell>` | Print completion for `bash`, `zsh`, or `fish`. |
|
|
73
73
|
| `economy menubar` | `install [--force]`, `start`, `stop`, or `uninstall` the macOS Economy Bar app. |
|
|
74
|
-
| `economy brains` | `gather`, `train`, `model [set|clear]`, and `status`. Fine-tuning requires the optional `@hasna/brains` package; gathering does not. |
|
|
75
74
|
| `economy events`, `economy webhooks` | Event emit/list/replay and event-subscription commands supplied by `@hasna/events`; use the nested `--help` for options. |
|
|
76
75
|
| `economy todos` | Display the bundled Economy roadmap, filter tasks, or show a task ID. This is project planning data, not live service status. |
|
|
77
76
|
|
package/docs/configuration.md
CHANGED
|
@@ -9,10 +9,10 @@ The default data directory is `~/.hasna/economy/` and the SQLite database is `~/
|
|
|
9
9
|
| `HASNA_ECONOMY_DB_PATH` | SQLite path; takes precedence over `ECONOMY_DB`. |
|
|
10
10
|
| `ECONOMY_DB` | Alternate SQLite path. `:memory:` is useful for tests. |
|
|
11
11
|
| `HASNA_ECONOMY_CONFIG_PATH` | Path to `config.json`; defaults under the data directory. |
|
|
12
|
-
| `
|
|
12
|
+
| `HASNA_ECONOMY_MACHINE_ID` | Machine identifier; otherwise Economy uses the normalized hostname. |
|
|
13
13
|
| `ECONOMY_TAG` | Fallback attribution tag on locally written sessions/requests. |
|
|
14
14
|
|
|
15
|
-
`economy config` reads and writes `config.json`. The defaults are `port=3456`, `default-period=today`, `auto-sync=true`, `sync-interval=30`, `alert-thresholds=[5,10,25,50,100]`, and `webhook-url=null`. At present, `webhook-url` drives budget notifications and `activeModel`
|
|
15
|
+
`economy config` reads and writes `config.json`. The defaults are `port=3456`, `default-period=today`, `auto-sync=true`, `sync-interval=30`, `alert-thresholds=[5,10,25,50,100]`, and `webhook-url=null`. At present, `webhook-url` drives budget notifications and `activeModel` records the selected model used by AI analysis; the other stored values are compatibility/settings metadata. Binary ports, periods, and watch intervals still come from command options or the environment described below.
|
|
16
16
|
|
|
17
17
|
## Account attribution
|
|
18
18
|
|
|
@@ -34,16 +34,29 @@ The same agent-specific pattern applies to all eight supported agents. Account k
|
|
|
34
34
|
|
|
35
35
|
## CLI/MCP cloud client
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
The CLI and MCP server resolve their credential through the `@hasna/contracts` 1.0.2 client resolver, FRESH ON EVERY CALL (and per request inside a long-lived MCP server, so a key rotation heals without a restart). The tiers, in order:
|
|
38
|
+
|
|
39
|
+
1. an explicit `--api-key` / `--profile` argument (CLI flags only)
|
|
40
|
+
2. a deliberate env pointer — `HASNA_ECONOMY_API_KEY_OVERRIDE`, `HASNA_PROFILE`, `HASNA_ECONOMY_API_KEY_REF`
|
|
41
|
+
3. the macOS Keychain — item `hasna.credentials.economy.api-key`, account `HASNA_STATION` → `hostname -s` → `$USER`
|
|
42
|
+
4. disk — `~/.hasna/economy/config/credentials` (0600, `HASNA_ECONOMY_API_KEY=…`; `HASNA_HOME` / `HASNA_CONFIG_HOME` move the root; XDG locations are never read)
|
|
43
|
+
5. `HASNA_ECONOMY_API_KEY` in the environment — legitimate, no deprecation notice
|
|
44
|
+
|
|
45
|
+
The authority follows the same ladder — `HASNA_ECONOMY_API_URL`, the Keychain `api-url` item, the credentials file — and DEFAULTS to the fleet gateway `https://api.hasna.com/economy` once a credential resolves, so a key alone is a complete configuration. An existing `/v1` suffix is normalized, otherwise it is appended. The unprefixed `ECONOMY_API_URL` / `ECONOMY_API_KEY` spellings are legacy aliases, accepted for one release at lower precedence.
|
|
46
|
+
|
|
47
|
+
**Fail closed (owner directive 2026-09-04).** A run without a credential from any tier exits non-zero, creates no SQLite file, and emits no `economy-local-fallback` event: an unconfigured client refuses to guess which dataset it serves. The error names every tier consulted.
|
|
48
|
+
|
|
49
|
+
**Local mode (the on-box SQLite store) is reachable only by explicit opt-in:**
|
|
38
50
|
|
|
39
51
|
```bash
|
|
40
|
-
export
|
|
41
|
-
export HASNA_ECONOMY_API_KEY='...'
|
|
52
|
+
export HASNA_ECONOMY_LOCAL=1
|
|
42
53
|
```
|
|
43
54
|
|
|
44
|
-
|
|
55
|
+
The unprefixed `ECONOMY_LOCAL=1` alias is accepted. The opt-in yields to every hosted signal (a URL, a key, or a pointer in the environment outranks it), and a local run prints one line on stderr — `economy: local mode (HASNA_ECONOMY_LOCAL=1) …` — so an unhosted run is never mistaken for a hosted one that came back empty.
|
|
56
|
+
|
|
57
|
+
The retired `*_STORAGE_MODE` / `*_MODE` variables — `HASNA_ECONOMY_STORAGE_MODE`, `HASNA_ECONOMY_MODE`, `ECONOMY_STORAGE_MODE`, `ECONOMY_MODE`, plus the accounts variants `HASNA_ACCOUNTS_*_MODE` — are inert: they select nothing, gate nothing, and error nothing (owner directive 2026-08-15). A wrapper may still export `HASNA_ECONOMY_STORAGE_MODE=cloud`; it changes nothing. Transport and backend come from the resolved credential / DSN above.
|
|
45
58
|
|
|
46
|
-
In cloud-client mode, data commands use the HTTP API
|
|
59
|
+
In cloud-client mode, data commands use the HTTP API: read commands answer from the API's GET routes (on-box auto-sync is skipped), and the explicit `economy sync` / `economy billing sync` verbs run the same on-box provider ingest against a scratch store and push the rows to `/v1/ingest`. Clients never need or use a Postgres DSN.
|
|
47
60
|
|
|
48
61
|
## REST server
|
|
49
62
|
|
|
@@ -54,13 +67,11 @@ economy serve --port 3456
|
|
|
54
67
|
economy-serve --port 3456
|
|
55
68
|
```
|
|
56
69
|
|
|
57
|
-
`ECONOMY_PORT` supplies the `economy-serve` default. `ECONOMY_BIND` (or `ECONOMY_HOST`) controls the local bind host. `
|
|
70
|
+
`ECONOMY_PORT` supplies the `economy-serve` default. `ECONOMY_BIND` (or `ECONOMY_HOST`) controls the local bind host. `HASNA_ECONOMY_API_TOKEN` enables the local shared-token check; send it as `Authorization: Bearer ...` or `X-Economy-Token`. (The unprefixed `ECONOMY_API_TOKEN` spelling is retired.)
|
|
58
71
|
|
|
59
72
|
Without a local token, the current server defaults to `0.0.0.0` and API routes are unauthenticated. Set a token and an intentional bind address before exposing a local-mode server to another host.
|
|
60
73
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
## Self-hosted server
|
|
74
|
+
## Server deployment
|
|
64
75
|
|
|
65
76
|
The server backend follows the database URL alone — `postgresql` when one of these is set, `sqlite` when none is:
|
|
66
77
|
|
|
@@ -70,7 +81,7 @@ ECONOMY_DATABASE_URL
|
|
|
70
81
|
DATABASE_URL
|
|
71
82
|
```
|
|
72
83
|
|
|
73
|
-
`HASNA_ECONOMY_STORAGE_MODE` (and `HASNA_ECONOMY_MODE`, `ECONOMY_STORAGE_MODE`, `ECONOMY_MODE`)
|
|
84
|
+
`HASNA_ECONOMY_STORAGE_MODE` (and `HASNA_ECONOMY_MODE`, `ECONOMY_STORAGE_MODE`, `ECONOMY_MODE`) never select a backend: the stale variables are inert and the server starts regardless — the DSN alone decides. The client follows the same rule: the variables select nothing, and API routing comes from the URL + key pair above.
|
|
74
85
|
|
|
75
86
|
Apply migrations with `economy-serve migrate`. `ECONOMY_PG_POOL_MAX` defaults to 5. A non-loopback server also requires one of `HASNA_ECONOMY_API_SIGNING_KEY`, `HASNA_API_SIGNING_KEY`, or `API_KEY_SIGNING_SECRET`; API keys are then verified by `@hasna/contracts`. The signing secret belongs only on the server.
|
|
76
87
|
|
|
@@ -84,5 +95,7 @@ See [REST API authentication](rest-api.md#authentication) for request headers an
|
|
|
84
95
|
| `MCP_HTTP_PORT` | MCP HTTP port; default 8860 and overridden by `--port`. |
|
|
85
96
|
| `ECONOMY_OTEL_PORT` | OTLP sidecar port; default 4318 and overridden by `--port`. |
|
|
86
97
|
| `ECONOMY_OTEL_BIND` | OTLP sidecar bind host; default `127.0.0.1`. |
|
|
98
|
+
| `HASNA_ECONOMY_INGEST_CACHE` | Path of the hosted `economy sync` mtime cache (a JSON file, never SQLite). Default `<cache root>/economy/ingest-cache.json`, where the cache root is `HASNA_CACHE_HOME`, else `~/Library/Caches/Hasna` (macOS) or `~/.cache/hasna`. Losing it costs one re-read; the server upserts are idempotent. |
|
|
99
|
+
| `HASNA_AGENT_REGISTRY_DB_PATH` | Local-lane path override for the MCP agent registry. Ignored when hosted; default under `HASNA_ECONOMY_LOCAL=1` is `agent-registry.db` in the data directory. |
|
|
87
100
|
|
|
88
101
|
Source- and billing-specific environment variables are listed in [Ingestion](ingestion.md).
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Cost certainty and subscription comparisons
|
|
2
|
+
|
|
3
|
+
Token counts and configured prices estimate usage value. They do not prove a
|
|
4
|
+
payment. An agent name does not identify an account's billing route: the same
|
|
5
|
+
agent can use a subscription, an API key or a router.
|
|
6
|
+
|
|
7
|
+
Unpriced models have an unavailable amount. The numeric SDK estimate and native
|
|
8
|
+
CLI/MCP estimate report `MODEL_PRICING_UNAVAILABLE`; they never return zero for a
|
|
9
|
+
missing price. An explicitly free model variant or a configured zero price can
|
|
10
|
+
return zero. Token counts must be nonnegative safe integers. Provider catalog
|
|
11
|
+
rates remain estimates; this repair does not refresh or attest their currency.
|
|
12
|
+
|
|
13
|
+
The savings endpoint describes an **estimated subscription comparison**:
|
|
14
|
+
|
|
15
|
+
`net_comparison_usd = included_consumed_usd - subscription_fee_usd`
|
|
16
|
+
|
|
17
|
+
Here, included consumption means the priced usage value of requests explicitly
|
|
18
|
+
identified as subscription-included. It is not provider credit consumption and
|
|
19
|
+
is not clipped to a plan's credit limit. The fee is the current configured or
|
|
20
|
+
observed monthly rate allocated across the selected full UTC calendar period.
|
|
21
|
+
Each month uses its own day count, including leap years and cross-month weeks.
|
|
22
|
+
This allocation is not a historical invoice or evidence of when a subscription
|
|
23
|
+
started. All-time fees require billing history and are unavailable here.
|
|
24
|
+
|
|
25
|
+
Paid API usage does not become savings. Separately observed on-demand charges
|
|
26
|
+
are not subtracted again from the included-usage comparison. Their account and
|
|
27
|
+
window identities must be known: duplicate cumulative readings use the latest
|
|
28
|
+
source observation, exact delta windows are deduplicated, and overlapping or
|
|
29
|
+
partially selected windows remain unavailable. Missing charge observations do
|
|
30
|
+
not prove that no charge occurred.
|
|
31
|
+
|
|
32
|
+
An exact account mapping is required between included requests and their plan.
|
|
33
|
+
Shared fees are counted once in the fleet comparison and are not allocated to
|
|
34
|
+
agents by usage share. A missing or ambiguous mapping, unknown fee, unpriced
|
|
35
|
+
model, or unknown billing route makes the comparison unavailable. Session-only
|
|
36
|
+
aggregates remain estimates. Legacy fee records retain their original amounts
|
|
37
|
+
with unknown provenance until reconciled.
|
|
38
|
+
|
|
39
|
+
`comparison_status` is `estimated`, `not_applicable`, or `unavailable`.
|
|
40
|
+
`net_comparison_usd` retains negative results; `saved_usd` is its positive part
|
|
41
|
+
only when a comparison is available. Unavailable amounts are JSON `null` and
|
|
42
|
+
display as `unavailable`, never `$0.00`. The response also carries known priced
|
|
43
|
+
usage, recorded metered amounts, unknown counts, and authored reason codes.
|
|
44
|
+
The SDK refuses the legacy savings contract rather than presenting its old
|
|
45
|
+
calculation. Deploy a compatible service before upgrading these consumers.
|
|
46
|
+
|
|
47
|
+
Existing Codex lifetime aggregates, Cursor cumulative daily requests and older
|
|
48
|
+
agent-name billing classifications need a separate preserved, guarded data
|
|
49
|
+
migration. Source repair alone does not rewrite or validate historical records.
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# Historical usage reconciliation
|
|
2
|
+
|
|
3
|
+
The former collectors could store a whole Codex session as one `-0` request,
|
|
4
|
+
a Hermes session as one `-rollup` request, a cumulative Cursor account summary
|
|
5
|
+
as a daily request, and token-priced Claude usage as `metered_api` based only
|
|
6
|
+
on the harness name. The repaired collectors do not establish the provenance
|
|
7
|
+
of historical rows. A matching identifier alone is not permission to change one.
|
|
8
|
+
|
|
9
|
+
Use the maintained server operator for a bounded inventory:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
economy-serve legacy-inventory --limit 25
|
|
13
|
+
economy-serve legacy-inventory --family codex_aggregate --limit 25
|
|
14
|
+
economy-serve legacy-inventory --family codex_aggregate --after '<last request id>'
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
It resolves the existing server PostgreSQL configuration, uses one read-only,
|
|
18
|
+
repeatable-read transaction, and returns counts, at most 100 candidate metadata
|
|
19
|
+
rows, exact logical row digests and a continuation cursor. It performs no
|
|
20
|
+
migration, ingestion, schema creation, backup, archive or record mutation.
|
|
21
|
+
It has no SQLite fallback. Database failures have a fixed redacted diagnostic.
|
|
22
|
+
|
|
23
|
+
The digest encoding is `postgres-row-json-text-v1`: SHA-256 of PostgreSQL's
|
|
24
|
+
`row_to_json(requests)::text` in UTF-8, with UTC, ISO/YMD dates and
|
|
25
|
+
`extra_float_digits=3`. Hashing occurs inside PostgreSQL before driver number
|
|
26
|
+
conversion, preserving nonfinite floats and large integers. Reconciliation
|
|
27
|
+
must use this same encoding against the same table schema. Only the digest
|
|
28
|
+
and selected metadata are returned. IDs and cursors retain the ingest contract
|
|
29
|
+
of up to 1,024 characters, including non-NUL controls, escaped in JSON output.
|
|
30
|
+
|
|
31
|
+
Each page and its counts share a snapshot. Separate pages can observe changes;
|
|
32
|
+
an exhausted cursor is not a frozen export of a concurrently changing store.
|
|
33
|
+
Both commands refuse reads when row-level security would filter the population;
|
|
34
|
+
they do not disable policies or grant the operator a bypass. Relation locks are
|
|
35
|
+
taken before the snapshot's first query, so concurrent schema changes cannot mix
|
|
36
|
+
old column metadata with newly shaped originals. Existing finite lock and query
|
|
37
|
+
timeouts still apply, and ordinary ingestion remains possible during these reads.
|
|
38
|
+
Counts refer to the documented source-shape predicates, not to proven errors.
|
|
39
|
+
The Claude class in particular needs a source and billing-provenance review:
|
|
40
|
+
some records may describe actual API usage. The inventory does not relabel them.
|
|
41
|
+
|
|
42
|
+
Before reconciliation, preserve and read back the exact originals, verify a
|
|
43
|
+
restored copy, review explicit targets and reasoned dispositions, and require
|
|
44
|
+
exact current-row preconditions plus a durable idempotent receipt. Quarantining
|
|
45
|
+
old aggregate representations must retain their original evidence and prevent
|
|
46
|
+
later ingestion from recreating the same double-counting. Reconstruct event
|
|
47
|
+
rows only from real source events. Unknown historical billing remains unknown;
|
|
48
|
+
never infer payment from a harness name or invent a historical price.
|
|
49
|
+
|
|
50
|
+
The inventory command is the read-only preparation step. Applying a disposition
|
|
51
|
+
requires the execution steps below and applicable production authority; inventory
|
|
52
|
+
supplies neither.
|
|
53
|
+
|
|
54
|
+
For explicitly reviewed candidates, prepare one bounded reconciliation proposal:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
economy-serve legacy-plan --input /absolute/path/selection.json
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The input is `economy.legacy-selection.v1`, with `items` containing 1–100
|
|
61
|
+
unique requests. Each item supplies `id`, `family`, `original_sha256` from the
|
|
62
|
+
inventory, a reasoned `disposition`, `reason`, and an `evidence_ref` identifying
|
|
63
|
+
the source review. The three aggregate families accept `quarantine_aggregate`;
|
|
64
|
+
Claude billing candidates accept `mark_billing_unknown`. An actual API charge
|
|
65
|
+
with verified provenance must not be selected merely because it matches the
|
|
66
|
+
Claude predicate. A supplied evidence reference is recorded, not authenticated
|
|
67
|
+
or approved by this tool. Never include credentials in this file.
|
|
68
|
+
|
|
69
|
+
The planner checks all selected originals against one read-only snapshot,
|
|
70
|
+
then binds each associated session and its complete request population. It
|
|
71
|
+
refuses missing or changed rows, changed family classification, missing sessions,
|
|
72
|
+
and selections spanning more than 10,000 requests. The bound is explicit: a
|
|
73
|
+
single larger session requires a separately reviewed procedure, not partial
|
|
74
|
+
membership. The file must be regular, at most 256 KiB, and cannot be a symlink;
|
|
75
|
+
nonblocking descriptor validation refuses FIFOs without waiting for a writer.
|
|
76
|
+
|
|
77
|
+
`original_encoding` matches the inventory. `members_sha256` hashes UTF-8 JSON
|
|
78
|
+
arrays of `[request_id, original_sha256]` pairs ordered by PostgreSQL `C`
|
|
79
|
+
collation, so unselected inserts, deletions and changes affect the precondition.
|
|
80
|
+
The plan also records table column definitions, database and relation locators,
|
|
81
|
+
the snapshot instant and a SHA-256 of its JSON body (everything preceding
|
|
82
|
+
`plan_sha256`, in emitted order). Database locators do not attest production
|
|
83
|
+
ownership; two installations can have the same local identifiers. Different
|
|
84
|
+
snapshot times intentionally produce different plan digests.
|
|
85
|
+
|
|
86
|
+
No originals leave the database and nothing is changed. This proposal is not
|
|
87
|
+
preservation, restore proof, approval, an idempotent apply receipt or a rollback.
|
|
88
|
+
The apply command preserves exact originals and atomically rechecks these
|
|
89
|
+
preconditions while excluding ingestion. Its runtime integration retains
|
|
90
|
+
quarantined evidence, refuses ingestion into protected request identities, and
|
|
91
|
+
uses effective request and session views for reporting. Excluding a request
|
|
92
|
+
while retaining its session aggregate would still double-count usage;
|
|
93
|
+
`legacy-plan` alone cannot repair that state.
|
|
94
|
+
|
|
95
|
+
Preserve a reviewed proposal with the server's existing PostgreSQL configuration:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
economy-serve legacy-preserve --input /absolute/path/plan.json --output /absolute/private-directory/originals.json
|
|
99
|
+
economy-serve legacy-rehearse --input /absolute/private-directory/originals.json
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
`legacy-preserve` rechecks the complete plan in one read-only snapshot and captures
|
|
103
|
+
every request belonging to its selected sessions, including unselected events,
|
|
104
|
+
plus each session original. A changed row, population, schema or store locator
|
|
105
|
+
refuses capture. Original PostgreSQL JSON stays text, preserving large integers
|
|
106
|
+
and nonfinite floats without a JavaScript number conversion. The capture is
|
|
107
|
+
bounded to 10,000 requests and 16 MiB of original row text; the final file cannot
|
|
108
|
+
exceed 32 MiB. Split a larger selection by session, never truncate it.
|
|
109
|
+
|
|
110
|
+
The output requires an existing owner-only directory. The file is created
|
|
111
|
+
exclusively with mode 0600, flushed and read back. An existing or interrupted
|
|
112
|
+
file is never overwritten or deleted. Standard output contains a compact hash
|
|
113
|
+
and count receipt, never original records. Retain the private capsule and receipt
|
|
114
|
+
under the applicable evidence and retention policy.
|
|
115
|
+
|
|
116
|
+
`legacy-rehearse` imports the raw preserved JSON through PostgreSQL's native row
|
|
117
|
+
types into transaction-local temporary tables, compares every reconstructed
|
|
118
|
+
original byte, then rolls back those tables. It changes no application records.
|
|
119
|
+
This verifies logical restoration of the selected sessions and their complete
|
|
120
|
+
request populations against the current table definitions. It is not a complete
|
|
121
|
+
database backup, production ownership attestation or disaster-recovery exercise.
|
|
122
|
+
Neither command authorizes quarantine or performs application or rollback of a
|
|
123
|
+
reconciliation.
|
|
124
|
+
|
|
125
|
+
## Apply, observe and roll back
|
|
126
|
+
|
|
127
|
+
Deploy the reviewed runtime integration and apply its appended PostgreSQL schema
|
|
128
|
+
migration before executing a reconciliation. Old migration bytes are unchanged.
|
|
129
|
+
The migration runner serializes competing invocations and commits each migration
|
|
130
|
+
and its completion marker atomically. After a lost commit response, rerun the
|
|
131
|
+
same migration command to read committed markers. Unexpected pre-existing,
|
|
132
|
+
unmarked definitions are refused rather than silently adopted or overwritten.
|
|
133
|
+
The operator never migrates on startup and never falls back to local storage.
|
|
134
|
+
Use the existing server configuration and an explicitly authorized database
|
|
135
|
+
principal; client agent credentials are not database operator authority.
|
|
136
|
+
|
|
137
|
+
```sh
|
|
138
|
+
economy-serve legacy-target
|
|
139
|
+
economy-serve legacy-apply --input /absolute/private-directory/apply.json --capsule /absolute/private-directory/originals.json
|
|
140
|
+
economy-serve legacy-receipt --operation '<original operation key>'
|
|
141
|
+
economy-serve legacy-rollback --input /absolute/private-directory/rollback.json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
An apply intent has exactly these fields:
|
|
145
|
+
|
|
146
|
+
```json
|
|
147
|
+
{
|
|
148
|
+
"schema": "economy.legacy-apply.v1",
|
|
149
|
+
"operation_key": "a-stable-key-for-this-reviewed-operation",
|
|
150
|
+
"target_sha256": "<digest returned by legacy-target>",
|
|
151
|
+
"plan_sha256": "<digest from the reviewed plan>",
|
|
152
|
+
"capsule_sha256": "<digest from the preserved capsule>",
|
|
153
|
+
"actor_ref": "<operator identity reference>",
|
|
154
|
+
"authority_ref": "<exact applicable authorization reference>"
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The angle-bracket values above are placeholders. Digests must be lowercase
|
|
159
|
+
64-character SHA-256 values. Operation keys accept 1–200 letters, digits, dots,
|
|
160
|
+
underscores, colons and hyphens; actor and authority references accept 1–512 of
|
|
161
|
+
those characters plus slashes. The target digest binds the effective host,
|
|
162
|
+
port, database, principal, connection options and TLS state resolved by the same
|
|
163
|
+
pool, including supported query and environment overrides, without exporting
|
|
164
|
+
credentials. It complements the preserved database and table locators; it does
|
|
165
|
+
not attest ownership. References record authority but do not authenticate it or
|
|
166
|
+
lift preservation and production gates.
|
|
167
|
+
|
|
168
|
+
Apply locks the ledger, sessions and requests before its repeatable-read snapshot,
|
|
169
|
+
rechecks every original and complete selected-session membership, and rehearses
|
|
170
|
+
restoration through the actual PostgreSQL types inside a savepoint. Reconstruction
|
|
171
|
+
is read-only except for its temporary rows. Rolling back that savepoint restores
|
|
172
|
+
write mode while retaining the outer locks through commit. Apply then records and
|
|
173
|
+
reads back the capsule, and appends the selected dispositions in one transaction.
|
|
174
|
+
It refuses stale rows, changed schemas, incomplete RLS populations and sessions
|
|
175
|
+
with an active reconciliation. Original requests and sessions are not rewritten
|
|
176
|
+
or removed. Quarantined aggregates disappear from effective reports; Claude
|
|
177
|
+
rows selected as unverified retain their recorded amount in the unknown bucket.
|
|
178
|
+
Affected session totals are recomputed from effective requests, and an empty
|
|
179
|
+
quarantined session cannot re-enter totals through the session fallback.
|
|
180
|
+
|
|
181
|
+
The response is a compact immutable receipt with operation, plan and capsule
|
|
182
|
+
bindings, counts and commit time. A response loss can occur after commit. Keep
|
|
183
|
+
the original intent and key, query `legacy-receipt`, and explicitly retry that
|
|
184
|
+
same intent if needed. A same-key replay returns the original receipt plus its
|
|
185
|
+
current active state; a different intent under that key is refused. Every
|
|
186
|
+
receipt and active-state observation uses one bounded read-only snapshot and
|
|
187
|
+
refuses policy-filtered visibility, including on replay. An absent
|
|
188
|
+
receipt does not prove that an in-flight command cannot still commit. Neither
|
|
189
|
+
the CLI nor the operator silently retries or invents a replacement key.
|
|
190
|
+
|
|
191
|
+
A rollback intent uses `schema: "economy.legacy-rollback.v1"`, its own stable
|
|
192
|
+
`operation_key`, the same target/plan/capsule bindings and actor/authority fields,
|
|
193
|
+
and an additional `apply_key` naming the original application. Rollback rechecks
|
|
194
|
+
all preserved source bytes and membership, then appends an immutable rollback
|
|
195
|
+
record. The original rows become effective again; neither application history
|
|
196
|
+
nor capsule is removed. If later ingestion or maintenance changed the selected
|
|
197
|
+
sessions, rollback refuses and preserves that later work. Prepare a fresh
|
|
198
|
+
reviewed reconciliation instead of forcing stale originals over newer data.
|
|
199
|
+
|
|
200
|
+
Protected request identities refuse ordinary update, delete and replacement.
|
|
201
|
+
Fresh event identities can still be ingested. The guards are integrity controls
|
|
202
|
+
for the application runtime, not protection from a database owner who can alter
|
|
203
|
+
the schema. Keep operator access separate from normal service credentials.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Ingest journal recovery and maintenance
|
|
2
|
+
|
|
3
|
+
The hosted collector writes an immutable command intent before its first POST.
|
|
4
|
+
A lost response leaves that intent pending. Reconciliation only reads the exact
|
|
5
|
+
hosted receipt: receipt absence, a different actor, authentication failure or an
|
|
6
|
+
unavailable authority never authorizes another POST. Hosted reads do not run
|
|
7
|
+
journal maintenance.
|
|
8
|
+
|
|
9
|
+
Completed commands share the existing limits of 1,000 commands and 64 MiB.
|
|
10
|
+
Admission reserves 4 KiB for each pending receipt and 16 KiB for fixed control
|
|
11
|
+
metadata. Server response extensions are discarded; the canonical receipt is
|
|
12
|
+
validated before persistence. Older directories over the byte admission limit
|
|
13
|
+
remain inspectable, but cannot admit new work until completed records retire.
|
|
14
|
+
Unresolved commands can legitimately exhaust capacity and must be reconciled.
|
|
15
|
+
|
|
16
|
+
A fresh command's own POST response with status 400, 409, 413 or 422 writes a
|
|
17
|
+
separate immutable refusal record bound to the exact intent, target and body
|
|
18
|
+
hash. Its status and a bounded authored reason are retained. Reconciliation
|
|
19
|
+
validates this terminal state and permits a different command, including a
|
|
20
|
+
corrected newer source version. The same rejected key returns the saved refusal
|
|
21
|
+
without another POST, even after restart. Status reports `rejected` separately
|
|
22
|
+
from uncertain `pending` commands; rejected originals still count against both
|
|
23
|
+
hard caps and are not eligible for completed-receipt Trash retirement. If many
|
|
24
|
+
rejections consume capacity, deliberate recovery remains necessary.
|
|
25
|
+
|
|
26
|
+
Only an invocation which freshly staged the intent can persist refusal proof,
|
|
27
|
+
and only from that command's first POST response. A timeout (including HTTP
|
|
28
|
+
408), a 5xx, malformed success, receipt GET failure or absent receipt never
|
|
29
|
+
creates refusal proof. Other 4xx statuses are conservatively retained without
|
|
30
|
+
terminal proof. Earlier-version pending intents without such proof remain
|
|
31
|
+
uncertain; a later 4xx cannot resolve an earlier ambiguous attempt. Interruption
|
|
32
|
+
before refusal proof is durable also remains uncertain. Receipt and refusal
|
|
33
|
+
records are disjoint; corrupt bindings, orphan records and dual outcomes fail
|
|
34
|
+
closed. No operator input can relabel an uncertain intent as rejected.
|
|
35
|
+
|
|
36
|
+
A bounded sweep starts at 64 commands, 48 MiB, or insufficient next-command
|
|
37
|
+
headroom. It retires at most 32 pairs or approximately 1 MiB per pass; a single
|
|
38
|
+
large pair is handled individually. Each pass has a 30-second network deadline.
|
|
39
|
+
The active journal remains bounded; Trash's recoverable remote retention and
|
|
40
|
+
unfinished transfer staging are governed by Trash's own policy.
|
|
41
|
+
|
|
42
|
+
## Recovery prerequisite
|
|
43
|
+
|
|
44
|
+
Enable automatic completed-record retirement explicitly with
|
|
45
|
+
`HASNA_ECONOMY_INGEST_RECOVERY=trash`. The client lazily loads the exact published
|
|
46
|
+
`@hasna/trash` 0.2.3 SDK. Trash resolves its own credential and station identity;
|
|
47
|
+
Economy never passes its credential to Trash, registers a station, starts a
|
|
48
|
+
backup, requests cold retrieval, or selects a local Trash store.
|
|
49
|
+
|
|
50
|
+
For a self-hosted Economy authority, also explicitly configure
|
|
51
|
+
`HASNA_TRASH_API_URL` for its supported Trash service. Without this setting,
|
|
52
|
+
Economy refuses before importing Trash or consulting an internal credential.
|
|
53
|
+
The fleet gateway may use the station's existing package-owned Trash resolver.
|
|
54
|
+
Run the owning Trash station readiness/setup procedure before enabling actual
|
|
55
|
+
maintenance. Native configuration drift is a station setup prerequisite, not
|
|
56
|
+
permission for Economy to rewrite the native configuration.
|
|
57
|
+
|
|
58
|
+
Missing recovery authority can defer automatic sweeping while admission still
|
|
59
|
+
fits. At capacity, or after any interrupted capture, ingestion reports
|
|
60
|
+
`INGEST_JOURNAL_MAINTENANCE_REQUIRED` with a bounded reason and preserves the
|
|
61
|
+
remaining source and recovery state. Do not clear the directory manually.
|
|
62
|
+
|
|
63
|
+
## Controls
|
|
64
|
+
|
|
65
|
+
The shared typed operation accepts:
|
|
66
|
+
|
|
67
|
+
- `{ "action": "status" }`: local counts and reservation; no hosted mutation.
|
|
68
|
+
- `{ "action": "reconcile" }`: resume the exact outstanding Trash transaction,
|
|
69
|
+
then read hosted receipts for pending commands. It never repeats ingestion.
|
|
70
|
+
- `{ "action": "maintain", "confirm": true, "limit": 32 }`: resume the exact
|
|
71
|
+
outstanding transaction and retire verified completed pairs. Pending commands
|
|
72
|
+
remain intact. Limit is 1–32. A capped pass reports remaining completed work.
|
|
73
|
+
|
|
74
|
+
Use `economy ingest journal status`, `economy ingest journal reconcile`, or
|
|
75
|
+
`economy ingest journal maintain --confirm --limit 32`. The MCP tool is
|
|
76
|
+
`ingest_journal` with the typed input above; SDK clients use `ingestJournal`.
|
|
77
|
+
All three surfaces return compact structured results. Refused CLI operations
|
|
78
|
+
exit nonzero; MCP refusals set `isError`. They never report successful sync.
|
|
79
|
+
|
|
80
|
+
## Preservation and interruptions
|
|
81
|
+
|
|
82
|
+
A permanent empty kernel-lock file serializes cooperating processes on Linux
|
|
83
|
+
and macOS. Process exit releases the lock. No file deletion, timed stale-owner
|
|
84
|
+
assumption, or process signal is used to take ownership. Do not replace that
|
|
85
|
+
file while the target journal exists.
|
|
86
|
+
|
|
87
|
+
Before capture, Economy revalidates the current actor's exact key/body-hash
|
|
88
|
+
receipt and compares its meaning with the local receipt. It captures the local
|
|
89
|
+
receipt first, then the intent, then their small maintenance manifest through
|
|
90
|
+
Trash. Both original SHA-256 and the SDK's distinct capsule identity are bound.
|
|
91
|
+
The SDK preserves byte/mode identity and verifies the hosted object before
|
|
92
|
+
source removal. The manifest records each exact Trash operation ID at the
|
|
93
|
+
snapshot checkpoint, before reservation. Earlier interruptions are located in
|
|
94
|
+
this target's dedicated Trash operation journal. Recovery resumes those IDs;
|
|
95
|
+
it never starts a replacement capture for an uncertain operation.
|
|
96
|
+
|
|
97
|
+
One immutable authority anchor remains after retirement. It references a
|
|
98
|
+
committed Economy receipt, contains no credential, and prevents a changed
|
|
99
|
+
principal from silently treating previously retired keys as new commands.
|
|
100
|
+
Restored records keep their original key/body and are reconciled normally.
|
|
101
|
+
Changing or losing the anchor's authority requires deliberate recovery under
|
|
102
|
+
an eligible original principal; successful authentication as another principal
|
|
103
|
+
is insufficient. The same-key path checks hosted history before staging or
|
|
104
|
+
sending a new command.
|
|
105
|
+
|
|
106
|
+
These are client source contracts. Publication, fleet readiness, actual hosted
|
|
107
|
+
capture/restore and independent release review require their own acceptance
|
|
108
|
+
evidence.
|