merge: bring the open-source readiness work onto the phase-13 branch

Merges gitea-ai/main (65 commits) into the phase-13 branch (419) so one
build carries both lines — the AIUI/assistant/container work and the
open-source readiness work (licensing, the marketplace DID signature layer,
the registry domain migration, the secrets and infrastructure scrub).

Every Rust file auto-merged. The container fixes from this branch and main's
registry-domain migration and node-name genericisation coexist without
manual intervention.

Conflict resolution — all of them were modify/delete, and all were resolved
in main's favour deliberately:

`.planning/**`, `scripts/deploy-to-target.sh` and `scripts/setup-aiui-server.sh`
were deleted by main's `6ba05996` ("security: remove all infrastructure and
internal process material from the repo") and added to .gitignore there.
Keeping this branch's copies would have re-committed internal process and
infrastructure material into a repo being prepared for publication, silently
undoing that cleanup. Resolved with `git rm --cached`, so every file remains
on disk locally and in this branch's history — it is untracked, not lost.
The remaining .planning files this branch added after the merge base were
untracked the same way, so the result is consistent rather than half-tracked.

Container suite 221/221 on the merged tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-08-08 09:02:32 -04:00
co-authored by Claude Opus 5
542 changed files with 5638 additions and 83054 deletions
+73
View File
@@ -1084,6 +1084,16 @@ class RPCClient {
relay_count: number
first_seen: string
nostr_pubkey: string
/**
* Whether the author proved control of the key their `author.did` names.
* `invalid` manifests are dropped during discovery and should never
* appear here; typed anyway so the UI fails safe rather than falling
* through to "signed" if that ever changes.
*/
signature?:
| { status: 'valid' }
| { status: 'missing' }
| { status: 'invalid'; reason: string }
}>
relay_count: number
}> {
@@ -1148,6 +1158,69 @@ class RPCClient {
})
}
/** This node's Lightning credential state. Digests and counts only — the
* backend never returns macaroon content, so nothing here is sensitive. */
async lndMacaroonStatus(): Promise<LndMacaroonStatus> {
return this.call({ method: 'lnd.macaroon-status', timeout: 30000 })
}
/** Begin a macaroon rotation. Returns as soon as the job is accepted; the
* work takes minutes (LND has to close and reopen its databases), so poll
* `lndMacaroonRotationProgress` for the outcome. */
async lndRotateMacaroons(password: string): Promise<{ status: string }> {
return this.call({
method: 'lnd.rotate-macaroons',
params: { password },
timeout: 30000,
})
}
async lndMacaroonRotationProgress(): Promise<LndRotationProgress> {
return this.call({ method: 'lnd.macaroon-rotation-progress' })
}
}
export type RotationStepState = 'pending' | 'running' | 'done' | 'failed' | 'skipped'
export interface LndRotationStep {
key: string
label: string
state: RotationStepState
detail: string | null
}
export interface LndRotationProgress {
running: boolean
/** null while running, then the verdict. Lets the UI tell "in progress"
* apart from "finished and failed". */
ok: boolean | null
started_at: string | null
finished_at: string | null
error: string | null
steps: LndRotationStep[]
/** Holds the OLD root key, so it is still secret. The UI tells the operator
* to delete it once every wallet app has been re-paired. */
backup_path: string | null
identity_pubkey: string | null
channels_before: number | null
channels_after: number | null
new_admin_macaroon_sha256: string | null
}
export interface LndMacaroonStatus {
installed: boolean
admin_macaroon_sha256: string | null
/** When LND last minted these credentials, host local time. */
issued_at: string | null
identity_pubkey: string | null
channels_open: number | null
channels_pending: number | null
/** Why LND could not be asked, when it could not. */
lnd_error: string | null
btcpay_uses_internal_lnd: boolean
/** null when BTCPay has no internal Lightning node — an absence, not a fault. */
btcpay_credential_current: boolean | null
rotation: LndRotationProgress
}
export const rpcClient = new RPCClient()