Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
55f2ec3dbc |
+3
-2
@@ -149,5 +149,6 @@ OTEL_SERVICE_NAME=mosaic-gateway
|
||||
# KEYCLOAK_CLIENT_ID=mosaic
|
||||
# KEYCLOAK_CLIENT_SECRET=
|
||||
|
||||
# The web login page discovers configured providers dynamically from
|
||||
# GET /api/sso/providers. No NEXT_PUBLIC_* provider feature flag is required.
|
||||
# Feature flags — set to true alongside provider credentials to show SSO buttons in the UI
|
||||
# NEXT_PUBLIC_WORKOS_ENABLED=true
|
||||
# NEXT_PUBLIC_KEYCLOAK_ENABLED=true
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ coverage
|
||||
*.tsbuildinfo
|
||||
.pnpm-store
|
||||
__pycache__/
|
||||
docs/.obsidian
|
||||
docs/reports/
|
||||
|
||||
# Step-CA dev password — real file is gitignored; commit only the .example
|
||||
infra/step-ca/dev-password
|
||||
|
||||
@@ -451,15 +451,24 @@ describe('AppModule federation gating', (): void => {
|
||||
);
|
||||
|
||||
it(
|
||||
'attributes an invalid monorepo-root dotenv tier to the default',
|
||||
'rejects an invalid explicit monorepo-root dotenv tier with a typed startup refusal',
|
||||
async (): Promise<void> => {
|
||||
const graph = await loadModuleGraphFromDotenv({
|
||||
const failure = await loadModuleGraphFromDotenv({
|
||||
rootEnvContents: 'MOSAIC_STORAGE_TIER=invalid\n',
|
||||
expectedProcessTier: 'invalid',
|
||||
});
|
||||
}).then(
|
||||
(): undefined => undefined,
|
||||
(error: unknown): unknown => error,
|
||||
);
|
||||
|
||||
expect(graph.imports).not.toContain(graph.federationModule);
|
||||
expectBootLogLine(graph.bootLogLines, 'local', 'default');
|
||||
expect(failure).toBeInstanceOf(Error);
|
||||
expect(failure).toMatchObject({
|
||||
name: 'MosaicConfigEnvironmentError',
|
||||
code: 'invalid_storage_tier',
|
||||
});
|
||||
expect((failure as Error).message).toBe(
|
||||
'Invalid MOSAIC_STORAGE_TIER; expected "local", "standalone", or "federated".',
|
||||
);
|
||||
},
|
||||
MODULE_IMPORT_TIMEOUT_MS,
|
||||
);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { resolveChatRuntimeMode } from './chat-runtime.js';
|
||||
|
||||
interface TypedSelectionFailure {
|
||||
readonly name: string;
|
||||
readonly code: string;
|
||||
}
|
||||
|
||||
describe('#1182 fail closed — a wrong answer must not be read as no answer', () => {
|
||||
it('FL-07 rejects an invalid explicit CHAT_HARNESS_RUNTIME before embedded construction', () => {
|
||||
let embeddedConstructionCount = 0;
|
||||
let failure: unknown;
|
||||
|
||||
try {
|
||||
const mode = resolveChatRuntimeMode({ CHAT_HARNESS_RUNTIME: 'pi-rpc-typo' });
|
||||
if (mode === 'legacy') {
|
||||
embeddedConstructionCount += 1;
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
failure = error;
|
||||
}
|
||||
|
||||
expect
|
||||
.soft(failure, 'invalid explicit runtime must produce a typed selection failure')
|
||||
.toMatchObject({
|
||||
name: 'ChatRuntimeConfigurationError',
|
||||
code: 'invalid_chat_harness_runtime',
|
||||
} satisfies TypedSelectionFailure);
|
||||
expect(
|
||||
embeddedConstructionCount,
|
||||
'invalid explicit runtime must fail before the embedded runtime is constructed',
|
||||
).toBe(0);
|
||||
});
|
||||
|
||||
it.each([{}, { CHAT_HARNESS_RUNTIME: '' }])(
|
||||
'preserves the documented transitional legacy default for true absence: %j',
|
||||
(env) => {
|
||||
expect(resolveChatRuntimeMode(env)).toBe('legacy');
|
||||
},
|
||||
);
|
||||
|
||||
it('anti-drift: runtime selection has no invalid-enum-to-legacy catch-all', () => {
|
||||
const source = readFileSync(new URL('./chat-runtime.ts', import.meta.url), 'utf8');
|
||||
|
||||
expect(
|
||||
source.includes("env['CHAT_HARNESS_RUNTIME'] === 'pi-rpc' ? 'pi-rpc' : 'legacy'"),
|
||||
'closed runtime enums must distinguish invalid explicit input from absence',
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
@@ -41,14 +41,28 @@ export class ChatRuntimeUnavailableError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
/** Typed startup refusal for an invalid explicit chat-runtime selection. */
|
||||
export class ChatRuntimeConfigurationError extends Error {
|
||||
readonly code = 'invalid_chat_harness_runtime' as const;
|
||||
|
||||
constructor() {
|
||||
super('Invalid CHAT_HARNESS_RUNTIME; expected "legacy" or "pi-rpc".');
|
||||
this.name = 'ChatRuntimeConfigurationError';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the process-wide chat runtime mode from the environment. Anything other
|
||||
* than the exact opt-in token `pi-rpc` keeps the legacy embedded runtime.
|
||||
* Resolves the process-wide chat runtime mode from the environment. Only true
|
||||
* absence (unset or empty) retains the documented transitional legacy default;
|
||||
* any other explicit value must be a member of the closed runtime enum.
|
||||
*/
|
||||
export function resolveChatRuntimeMode(
|
||||
env: Record<string, string | undefined> = process.env,
|
||||
): ChatRuntimeMode {
|
||||
return env['CHAT_HARNESS_RUNTIME'] === 'pi-rpc' ? 'pi-rpc' : 'legacy';
|
||||
const runtime = env['CHAT_HARNESS_RUNTIME'];
|
||||
if (runtime === undefined || runtime === '') return 'legacy';
|
||||
if (runtime === 'legacy' || runtime === 'pi-rpc') return runtime;
|
||||
throw new ChatRuntimeConfigurationError();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# Administrator Guide
|
||||
|
||||
> **Status:** Partially migrated. Current SSO and local upgrade/recovery procedures are available; held procedures are labeled non-operative.
|
||||
|
||||
This book is the canonical home for installation, configuration, deployment, routine operations, security controls, incident response, and recovery. User workflows belong in [`USER-GUIDE/`](../USER-GUIDE/); implementation and contributor material belongs in [`DEVELOPER-GUIDE/`](../DEVELOPER-GUIDE/).
|
||||
|
||||
## Start here
|
||||
|
||||
- [Documentation atlas](../README.md) — placement rules and source-of-truth boundaries.
|
||||
- [Documentation sitemap](../SITEMAP.md) — resolvable current navigation and authority-gated migration summary.
|
||||
- [Product requirements](../PRD.md) — normative requirements, currently marked draft.
|
||||
- [Operations index](operations/README.md) — current local procedures and explicitly held operational outlines.
|
||||
- [Security index](security/README.md) — current SSO provider configuration.
|
||||
|
||||
## Chapter map
|
||||
|
||||
| Chapter | Scope | Status |
|
||||
| ------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------- |
|
||||
| `installation/` | Prerequisites, installation, and first deployment. | Scaffold only. |
|
||||
| `configuration/` | Environment, provider, tier, and runtime configuration. | Scaffold only. |
|
||||
| `deployment/` | Topologies, rollout, migration, and upgrade procedures. | Scaffold only. |
|
||||
| [`operations/`](operations/README.md) | Health, observability, routine operation, and maintenance. | Local upgrade/recovery is current; connector lease operations are held. |
|
||||
| [`security/`](security/README.md) | Authentication, authorization, SSO, secrets, and security controls. | SSO provider guide is current; other pages are planned. |
|
||||
| `recovery/` | Incident response, backup, rollback, and recovery. | Scaffold only. |
|
||||
|
||||
Every promoted page must be added to this index and to [`SITEMAP.md`](../SITEMAP.md) in the same migration slice.
|
||||
|
||||
## Evidence — not current operator guidance
|
||||
|
||||
- [`P8-003 performance report`](../reports/qa/p8-003-performance-optimization.md) — historical performance evidence; implementation alignment is partial, and production metrics remain unverified. It is not an operational SLO or runbook.
|
||||
|
||||
## Migration backlog — not current operator guidance
|
||||
|
||||
These are source candidates, not verified runbooks:
|
||||
|
||||
- `_old_structure/guides/admin-guide.md` — quarantined historical source; verify claims before promotion.
|
||||
- `_old_structure/guides/deployment.md` — quarantined historical source; deployment commands and assumptions remain held.
|
||||
- See the [documentation catalog](../reports/documentation/2026-08-10-docs-catalog-audit.md) for file-level dispositions.
|
||||
|
||||
Do not treat a migration candidate as current until its commands, paths, permissions, and safety status are checked against source and tests.
|
||||
|
||||
## Authoring boundary
|
||||
|
||||
New administrator documentation belongs under one of the chapter directories above. Operationally sensitive pages must identify prerequisites, ownership, source-of-truth dependencies, and whether any procedure is current, illustrative, held, or non-operative.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[PRD|Product requirements]]
|
||||
- [[DEVELOPER-GUIDE/architecture/README|Architecture index]]
|
||||
@@ -1,19 +0,0 @@
|
||||
# Administrator Operations
|
||||
|
||||
> **Status:** Partially migrated. Procedures explicitly identify whether they are current or held.
|
||||
|
||||
## Current procedures
|
||||
|
||||
- [Upgrade safety and recovery](upgrade-safety-and-recovery.md) — installed-CLI and local-PGlite upgrade, rollback, and framework-configuration recovery.
|
||||
|
||||
## Held procedures
|
||||
|
||||
- [Mos connector lease operations](mos-connector-lease-operations.md) — non-operative M1 outline while the gateway policy remains deny-all and no connector is activated.
|
||||
|
||||
A held page is architecture and readiness context, not command authority. PostgreSQL, federated, bare-metal, Compose, Gateway/Web activation, and migration-runner procedures remain outside the current local route unless a later page explicitly removes the hold with verified evidence.
|
||||
|
||||
## Related
|
||||
|
||||
- [[ADMIN-GUIDE/README|Administrator guide]]
|
||||
- [[ADMIN-GUIDE/security/README|Administrator security]]
|
||||
- [[DEVELOPER-GUIDE/architecture/README|Architecture index]]
|
||||
@@ -1,79 +0,0 @@
|
||||
# Mos Connector Lease Operations — M1
|
||||
|
||||
> **Status:** Held / non-operative.
|
||||
> **Operational authority:** None. This page is a future runbook outline, not a current command, endpoint, migration, or activation procedure.
|
||||
> **Hold condition:** The gateway's `DenyConnectorLeasePolicy` remains the default policy and rejects every lease and grant operation. No connector is activated by this page.
|
||||
|
||||
## Current state
|
||||
|
||||
M1 provides an implemented lease, fencing, audit, and gateway policy boundary. It does not currently provide an operator-facing lease endpoint, activate a connector, cut over a channel, or connect an existing runtime provider to `ConnectorExecutionContext`. The default gateway module is deny-all, so operators must not treat the schema or internal service as an available lease-control surface.
|
||||
|
||||
There is no current operator command sequence to acquire, renew, take over, release, or grant connector authority. Do not attempt to operate the held procedure through direct database writes or by bypassing the gateway policy. Any future activation requires a separately approved server-side policy, concrete adapter, downstream fencing design, and an updated operational runbook.
|
||||
|
||||
## Held future procedure — not current command authority
|
||||
|
||||
The following records the intended shape of a later runbook. It is deliberately non-operative while deny-all remains:
|
||||
|
||||
### Events and evidence to monitor later
|
||||
|
||||
If an authorized policy and adapter are activated in a future work package, correlation IDs may be used to inspect `connector_lease_audit_log` events:
|
||||
|
||||
| Event | Meaning |
|
||||
| ---------- | ---------------------------------------------------------------------------------- |
|
||||
| `acquire` | First holder inserted for an unused binding |
|
||||
| `renew` | Current holder heartbeat extended the TTL |
|
||||
| `takeover` | Authorized compare-and-swap replaced the holder and incremented epoch |
|
||||
| `release` | Current holder explicitly relinquished authority |
|
||||
| `expiry` | An expired current lease was observed |
|
||||
| `reject` | Policy, compare-and-swap, expiry, scope, or fencing validation denied an operation |
|
||||
|
||||
Audit records are metadata-only. Raw grant objects, connector payloads, scopes, tokens, approval references, and credentials must never be added to audit output. The current schema does not independently enforce append-only storage; database-level protection remains a future hardening requirement.
|
||||
|
||||
### Held incident-review outline
|
||||
|
||||
For a future suspected duplicate or stale connector effect, an approved operator procedure would:
|
||||
|
||||
1. correlate the attempted operation with its `reject`, `takeover`, or `expiry` event;
|
||||
2. compare the durable row's connector ID, lease UUID, epoch, expiry, and release time with the adapter's normalized execution context;
|
||||
3. treat an old epoch, old lease UUID, expired lease, or released lease as non-authoritative rather than retrying it as the old holder;
|
||||
4. use only the authorized takeover path with the observed expected epoch, never ordinary acquire, for an expired or released row; and
|
||||
5. preserve evidence without assuming lease fencing provides exactly-once replay safety if an external effect may already have occurred.
|
||||
|
||||
These are held review requirements, not instructions to bypass the current deny-all policy.
|
||||
|
||||
### Held migration and rollback notes
|
||||
|
||||
The checked-in `0016_salty_morlocks.sql` artifact is additive: it creates the lease and audit tables and indexes without changing existing authorization/session tables. A future database rollout would still require the repository's approved migration, backup, verification, and rollback controls. Application rollback would leave additive lease/audit tables in place; dropping them would destroy evidence and is not an automatic rollback step.
|
||||
|
||||
This page does not authorize running migrations, connecting to PostgreSQL, initializing PGlite, or starting a connector. Those activities remain outside this held procedure and subject to repository/runtime gates.
|
||||
|
||||
### Held security prerequisites
|
||||
|
||||
Before this page could become operative, the activation work would need to demonstrate at least:
|
||||
|
||||
- tenant authority derived from authenticated gateway context, not connector request fields;
|
||||
- authorized policy decisions over normalized identity and scopes, with policy TTL handling based on the requested input and coordinator hard caps still applied;
|
||||
- explicit takeover authorization and expected-epoch compare-and-swap;
|
||||
- application-boundary normalization plus any separately approved database constraints or protections;
|
||||
- validation and rejection audit before adapter side effects;
|
||||
- a concrete adapter that consumes and propagates the normalized epoch/context; and
|
||||
- existing authorization and exact-action approval controls remaining in force.
|
||||
|
||||
M1 currently satisfies the boundary contract and default-deny posture, not these activation prerequisites.
|
||||
|
||||
## Explicit non-goals while held
|
||||
|
||||
This page does not authorize or claim:
|
||||
|
||||
1. lease administration from the dashboard, CLI, HTTP, SQL console, or a connector;
|
||||
2. production connector or channel activation;
|
||||
3. exactly-once delivery, side-effect journaling, checkpoint/handoff recovery, or replay safety;
|
||||
4. automatic failover, rollback, or stale-effect recovery across Claude, Pi, Codex, Matrix, tmux, or provider sessions; or
|
||||
5. database-enforced audit immutability or database-enforced application normalization.
|
||||
|
||||
The page may be promoted to an operative runbook only after deny-all is intentionally replaced, concrete adapters are reviewed, activation evidence exists, and this hold is explicitly removed by the owning work package.
|
||||
|
||||
## Related contract
|
||||
|
||||
- [M1 logical identity and fencing decision](../../DEVELOPER-GUIDE/architecture/decisions/mos-runtime-portability-m1.md)
|
||||
- [MOS-PORT requirements](../../PRD.md#mos-runtime-portability-workstream-mos-port)
|
||||
@@ -1,248 +0,0 @@
|
||||
# Upgrade safety and recovery
|
||||
|
||||
> **Supported route:** an already installed `mosaic` CLI using the local PGlite
|
||||
> configuration. This is a filesystem and CLI runbook; it does not activate a
|
||||
> service or connect to a database.
|
||||
|
||||
This page covers the supported upgrade, rollback, health, and recovery checks for
|
||||
Mosaic framework configuration under `MOSAIC_HOME`. It deliberately does not
|
||||
turn the repository's deployment or PostgreSQL material into an operative
|
||||
procedure.
|
||||
|
||||
## Support boundary
|
||||
|
||||
Use this runbook only when all of the following are true:
|
||||
|
||||
- `mosaic` resolves to the installed Mosaic CLI (`command -v mosaic`).
|
||||
- The active application configuration is the local tier: `tier: "local"`,
|
||||
`storage.type: "pglite"`, and `queue.type: "local"`.
|
||||
- `DATABASE_URL` is unset. An inherited PostgreSQL DSN is outside this route and
|
||||
must be removed before continuing.
|
||||
- `MOSAIC_STORAGE_TIER` is unset or `local`; standalone and federated overrides
|
||||
are outside this route.
|
||||
- No Gateway, Web, Compose, or other service activation is required.
|
||||
|
||||
The following routes are **held/non-operative** in this guide:
|
||||
|
||||
| Route or operation | Status |
|
||||
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| PostgreSQL-backed `standalone` storage | Held; do not activate or probe it here. |
|
||||
| Federated storage and peers | Held; do not activate or probe it here. |
|
||||
| Bare-metal deployment | Held; no service installation or lifecycle action is authorized. |
|
||||
| Gateway/Web activation or HTTP health checks | Held; `/health`, `/health/ready`, and `mosaic gateway ...` are not evidence for this route. |
|
||||
| Compose startup | Held; do not start a Compose profile or the full stack. |
|
||||
| Migration runners and tier migration | Held; do not run `mosaic-db-migrator`, `pnpm --filter @mosaicstack/db db:migrate`, `mosaic storage migrate`, or `mosaic storage migrate-tier`. |
|
||||
|
||||
A command being present in the CLI does not make a held route operative.
|
||||
|
||||
## Storage and path terminology
|
||||
|
||||
Keep these locations separate:
|
||||
|
||||
- **`MOSAIC_HOME`** — the framework/operator configuration directory. It
|
||||
defaults to `~/.config/mosaic` and can be overridden with `MOSAIC_HOME`.
|
||||
- **PGlite data** — the local, in-process database. The checked-in local config
|
||||
uses `.mosaic/storage-pglite` as its storage `dataDir`; `.mosaic/queue` is the
|
||||
local queue directory. These are project data, not framework configuration.
|
||||
- **Durable upgrade snapshots** — operator-file snapshots stored under
|
||||
`${XDG_STATE_HOME:-$HOME/.local/state}/mosaic/backups/`. They are outside
|
||||
`MOSAIC_HOME` and do not contain a PostgreSQL dump.
|
||||
|
||||
The configuration tier is named `local`; the storage CLI reports the backend as
|
||||
`pglite`. PGlite is not PostgreSQL and does not require a PostgreSQL server.
|
||||
Local PGlite schema setup is adapter-owned; this page does not authorize a
|
||||
separate migration runner.
|
||||
|
||||
## Pre-upgrade health gate
|
||||
|
||||
Run these checks from a shell that has no inherited database DSN:
|
||||
|
||||
```bash
|
||||
command -v mosaic
|
||||
mosaic --version
|
||||
mosaic config path
|
||||
test -d "$(mosaic config path)"
|
||||
|
||||
env -u DATABASE_URL -u MOSAIC_STORAGE_TIER mosaic storage tier show
|
||||
env -u DATABASE_URL -u MOSAIC_STORAGE_TIER mosaic storage status
|
||||
mosaic restore --list
|
||||
```
|
||||
|
||||
For the supported route, the storage checks should report the `pglite` backend
|
||||
and say that no network check is needed. `mosaic storage status` reports
|
||||
`PGLITE_DATA_DIR` when that variable is set; otherwise it reports the CLI's
|
||||
`:memory:` fallback. That output is an inspection of the CLI environment, not a
|
||||
claim that PGlite contents are healthy or durable.
|
||||
|
||||
If `DATABASE_URL` is set, stop. Do not point it at a local PostgreSQL instance
|
||||
to make the check pass. If the active configuration is not local/PGlite, stop;
|
||||
no operative route is documented here.
|
||||
|
||||
The supported health gate is intentionally limited to CLI resolution, framework
|
||||
configuration path, local storage selection, and available upgrade snapshots.
|
||||
It does not prove Gateway/Web readiness, provider connectivity, queue health, or
|
||||
PGlite data integrity.
|
||||
|
||||
## Safe upgrade procedure
|
||||
|
||||
1. **Record the baseline.** Save the output of `mosaic --version`,
|
||||
`mosaic config path`, and `mosaic restore --list`. Do not copy secrets into a
|
||||
ticket or report.
|
||||
2. **Check for updates without installing them:**
|
||||
|
||||
```bash
|
||||
mosaic update --check
|
||||
```
|
||||
|
||||
Exit status `0` means no update was reported; status `2` means an update is
|
||||
available. Other failures are not a successful health result. The check is a
|
||||
package-registry check and does not start Mosaic services or access storage.
|
||||
|
||||
3. **Run the installed-CLI upgrade when approved:**
|
||||
|
||||
```bash
|
||||
mosaic update
|
||||
```
|
||||
|
||||
The command updates the installed `@mosaicstack/*` packages through npm and,
|
||||
when the framework package changed or framework drift is detected, re-seeds
|
||||
framework files in keep mode. Leave the default re-seed enabled. Do not use
|
||||
`--relaunch` in this runbook: that option can restart durable fleet agents
|
||||
and is outside the supported no-activation route. `--no-reseed` is also not a
|
||||
normal upgrade path because it intentionally leaves framework files stale.
|
||||
|
||||
4. **Repeat the health gate.** Confirm the CLI version, the same
|
||||
`MOSAIC_HOME`, the local/PGlite storage selection, and the snapshot listing.
|
||||
A successful framework upgrade must not be used as evidence that a held
|
||||
Gateway, Web, PostgreSQL, or federated route is ready.
|
||||
|
||||
Do not replace this procedure with a direct edit of `~/.config/mosaic`, a
|
||||
repository `tools/install.sh` invocation, a Compose startup, or a migration
|
||||
command. The supported operator entry point for this page is the installed
|
||||
`mosaic update` command.
|
||||
|
||||
## What an upgrade protects
|
||||
|
||||
For an existing keep-mode installation, the framework installer takes two
|
||||
separate snapshots before the file sync:
|
||||
|
||||
1. An ephemeral whole-directory snapshot under `${TMPDIR:-/tmp}/` is used to
|
||||
restore the previous framework directory if the sync is interrupted or
|
||||
fails. If that restore cannot complete, the installer prints the retained
|
||||
temporary snapshot path for manual recovery.
|
||||
2. A durable snapshot captures the existing operator-owned files before the
|
||||
upgrade at:
|
||||
|
||||
```text
|
||||
${XDG_STATE_HOME:-$HOME/.local/state}/mosaic/backups/pre-update-<UTC timestamp>/
|
||||
```
|
||||
|
||||
Snapshot directories are mode `0700`; captured files are mode `0600`.
|
||||
Retention is five snapshots by default and can be changed with
|
||||
`MOSAIC_BACKUP_RETENTION`. A durable snapshot failure is a warning and does
|
||||
not replace the manifest and crash-rollback protections.
|
||||
|
||||
After the keep-mode sync, the installer compares each captured operator file
|
||||
with its target. If a file was changed or removed unexpectedly, it restores the
|
||||
snapshot copy and emits a warning. A symlinked parent is not followed; that
|
||||
case is left for manual recovery from the snapshot path.
|
||||
|
||||
Keep mode is manifest-driven and fail-safe for operator paths, but it does not
|
||||
mean every file under `MOSAIC_HOME` is user-owned. The framework contract files
|
||||
`CONSTITUTION.md`, `AGENTS.md`, and `STANDARDS.md` are refreshed by upgrades;
|
||||
keep local policy in the supported local overlays rather than editing those
|
||||
contract files as rollback data. A durable snapshot is for operator-owned
|
||||
configuration, not for the installed npm package, framework-owned contracts, or
|
||||
PGlite data.
|
||||
|
||||
## Rollback and recovery
|
||||
|
||||
### If the upgrade fails or is interrupted
|
||||
|
||||
The framework sync attempts an automatic rollback from its ephemeral snapshot.
|
||||
Do not delete `MOSAIC_HOME`, the PGlite data directory, or the temporary snapshot
|
||||
named in the error. Preserve the command output, then run the health gate.
|
||||
|
||||
If the installed framework reports that the automatic restore did not complete,
|
||||
use the durable snapshot procedure below. The durable snapshot is the recovery
|
||||
pointer that survives a successful upgrade and the removal of the temporary
|
||||
snapshot.
|
||||
|
||||
### Restore operator configuration from a durable snapshot
|
||||
|
||||
`mosaic restore` is confirmation-gated and reports counts and relative paths,
|
||||
not file contents. First list snapshots, then preview the selected timestamp:
|
||||
|
||||
```bash
|
||||
mosaic restore --list
|
||||
mosaic restore --from <UTC-timestamp> --dry-run
|
||||
```
|
||||
|
||||
If the preview is correct, run the interactive restore:
|
||||
|
||||
```bash
|
||||
mosaic restore --from <UTC-timestamp>
|
||||
```
|
||||
|
||||
Use `--yes` only when the overwrite has been explicitly approved:
|
||||
|
||||
```bash
|
||||
mosaic restore --from <UTC-timestamp> --yes
|
||||
```
|
||||
|
||||
The timestamp is the value printed by `mosaic restore --list`; the command also
|
||||
accepts the full `pre-update-<timestamp>` name. For a non-default configuration
|
||||
home, pass the same target explicitly:
|
||||
|
||||
```bash
|
||||
mosaic restore --mosaic-home "$MOSAIC_HOME" --from <UTC-timestamp>
|
||||
```
|
||||
|
||||
After restoring, repeat the health gate. Restore writes only the operator
|
||||
surface represented by that snapshot. It does not downgrade the installed CLI,
|
||||
restore framework-owned contract files, restore `.mosaic/storage-pglite`, or
|
||||
run any migration.
|
||||
|
||||
### If local PGlite data is missing or corrupt
|
||||
|
||||
Do not use a framework snapshot as a database backup. Do not run a migration
|
||||
runner, start PostgreSQL, start Compose, or activate Gateway/Web to investigate.
|
||||
The current CLI does not provide a wired PGlite export/import operation;
|
||||
`mosaic storage export` and `mosaic storage import` only print direct-copy
|
||||
guidance. Preserve the configured PGlite data directory and route data
|
||||
restoration through the held data-layer procedure rather than improvising a
|
||||
recursive delete or copy.
|
||||
|
||||
### Recovery decision tree
|
||||
|
||||
- **CLI or framework path is wrong:** stop, verify `command -v mosaic`,
|
||||
`mosaic --version`, `MOSAIC_HOME`, and `mosaic config path`; do not activate a
|
||||
held service route.
|
||||
- **Upgrade failed during framework sync:** use the installer's automatic
|
||||
rollback first; if it reports incomplete recovery, list and preview the
|
||||
durable snapshot, then restore it interactively.
|
||||
- **An operator file changed after a reported-successful upgrade:** select the
|
||||
pre-upgrade snapshot with `mosaic restore --list`, preview it with `--dry-run`,
|
||||
and restore only after reviewing the relative-path plan.
|
||||
- **PGlite data is affected:** preserve the data directory and stop at the
|
||||
boundary described above. Framework rollback cannot recover database rows.
|
||||
- **Output requests PostgreSQL, federated, bare-metal, Compose, Gateway/Web, or
|
||||
a migration runner:** stop; that is a held/non-operative route, not a next
|
||||
command for this runbook.
|
||||
|
||||
## Post-recovery verification
|
||||
|
||||
Run the non-mutating checks again:
|
||||
|
||||
```bash
|
||||
mosaic --version
|
||||
mosaic config path
|
||||
env -u DATABASE_URL -u MOSAIC_STORAGE_TIER mosaic storage tier show
|
||||
env -u DATABASE_URL -u MOSAIC_STORAGE_TIER mosaic storage status
|
||||
mosaic restore --list
|
||||
```
|
||||
|
||||
A green result here means the installed CLI resolves, the framework path is
|
||||
present, the CLI selects local PGlite without a network probe, and snapshots can
|
||||
be enumerated. It does not certify database contents or any held deployment
|
||||
route.
|
||||
@@ -1,20 +0,0 @@
|
||||
# Security
|
||||
|
||||
> **Status:** Partially migrated. The SSO provider and Discord ingress security pages are current.
|
||||
|
||||
This chapter will contain authentication, authorization, SSO, secrets, RBAC, and security-control guidance for administrators.
|
||||
|
||||
## Planned pages
|
||||
|
||||
- [`sso-providers.md`](sso-providers.md) — current provider configuration, discovery, callbacks, and failure modes.
|
||||
- [`discord-ingress.md`](discord-ingress.md) — current Discord service authentication, allowlists, bindings, roles, replay, and failure controls.
|
||||
- `secrets.md` — document general secret handling after source/configuration verification.
|
||||
- `rbac.md` — document roles and permissions from the canonical implementation.
|
||||
|
||||
The current SSO page reflects dynamic provider discovery. The Discord page documents only the verified Discord compatibility boundary; it does not claim Telegram or Matrix parity. Do not revive retired root documents or add frontend feature flags that the web flow does not consume.
|
||||
|
||||
## Related
|
||||
|
||||
- [`Administrator guide`](../README.md)
|
||||
- [`API documentation`](../../API/README.md)
|
||||
- [[DEVELOPER-GUIDE/architecture/README|Architecture index]]
|
||||
@@ -1,137 +0,0 @@
|
||||
# Discord ingress security
|
||||
|
||||
> **Status:** Current Discord behavior only. Telegram shared-contract parity, Matrix channel ingress, and a gateway-wide shared adapter registry are not implemented or are not proven by the current source/tests.
|
||||
>
|
||||
> **Last verified:** 2026-08-10 against the Discord plugin, gateway ingress/authentication code, and focused tests linked in [Evidence](#evidence).
|
||||
>
|
||||
> **Audience:** Administrators provisioning the Discord remote-control boundary.
|
||||
|
||||
This page documents the security boundary that exists today. It is not a deployment recipe for Telegram or Matrix, and it does not turn the gateway's lifecycle plugin list into a universal channel registry.
|
||||
|
||||
## Security model
|
||||
|
||||
Discord ingress has two current layers:
|
||||
|
||||
1. **Native Discord admission** in `@mosaicstack/discord-plugin` applies guild/channel/user allowlists, pairing, role, rate, and thread rules before a thread is created or a message is dispatched.
|
||||
2. **Gateway compatibility admission** authenticates the Discord Socket.IO service, verifies the signed envelope again, re-checks the allowlists and binding, validates the conversation route, rejects replayed native message IDs, and then dispatches the message to the trusted agent configuration.
|
||||
|
||||
The current gateway namespace is `/chat`. The Discord plugin connects with a Socket.IO handshake value named `discordServiceToken`; this is distinct from the environment variable name `DISCORD_SERVICE_TOKEN` that supplies the value to the plugin and gateway.
|
||||
|
||||
### Admission and authorization order
|
||||
|
||||
For an inbound guild message, the current implementation:
|
||||
|
||||
1. Ignores bot-authored messages and messages without a guild. Discord DMs are therefore not handled by this ingress path, even though the client requests a direct-message intent.
|
||||
2. Uses the configured thread parent as the authorization channel for a thread. A normal Discord category parent is never substituted for a text channel.
|
||||
3. Requires the guild, authorization channel, and user to appear in their respective allowlists.
|
||||
4. Resolves a configuration-owned binding and paired user. `viewer` cannot send a turn. Ordinary `send` requires `operator` or `admin`; `approve` and `stop` require `admin`.
|
||||
5. Applies the message and mention-thread rate limits before any thread creation or gateway dispatch.
|
||||
6. Derives the route from the binding's logical-agent instance and the response channel/thread. The route does not accept a provider, model, harness, process, or runtime-session selector from Discord.
|
||||
7. Creates or reuses a thread only after the checks above pass.
|
||||
|
||||
The gateway then verifies the HMAC-SHA-256 envelope with `DISCORD_SERVICE_TOKEN`, re-applies the allowlists and binding/role check, requires the conversation ID to match the bound logical agent and channel/thread, and claims the native Discord message ID in a bounded replay cache. The default replay cache is in-process, retains IDs for 15 minutes, and is bounded at 10,000 entries; it is not a durable inbox.
|
||||
|
||||
For ordinary chat, the gateway attempts persistence and dispatch using `DISCORD_SERVICE_USER_ID`; `DISCORD_SERVICE_TENANT_ID` is used when configured and otherwise ordinary chat falls back to the service user ID as its tenant. The Discord external route is not a UUID, while persisted conversation IDs are UUIDs; no current route-to-UUID mapping proves that ordinary Discord persistence succeeds. The gateway may continue dispatch after a persistence/binding failure, so successful live delivery is not durable-history evidence.
|
||||
|
||||
Privileged approval and stop additionally require a configured tenant, a paired `mosaicUserId`, and a previously enrolled durable session. The durable session's logical agent must match the binding before approval or stop is accepted. The approval is consumed once against the exact runtime target; the Discord service account is not substituted for the approving paired user.
|
||||
|
||||
The trusted `agentConfigId` in each binding is resolved by the gateway. Its provisioned agent name must exactly equal `instanceId`. Discord cannot choose an arbitrary agent, provider, or model in the message payload, and Discord ingress does not use the general routing engine for a new session.
|
||||
|
||||
## Required configuration
|
||||
|
||||
The gateway's current plugin factory is in [`plugin.module.ts`](../../../apps/gateway/src/plugin/plugin.module.ts). When `DISCORD_BOT_TOKEN` is present, the following Discord values are required or validated as shown:
|
||||
|
||||
| Name | Required/current behavior |
|
||||
| --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `DISCORD_BOT_TOKEN` | Enables the Discord plugin and supplies the Discord bot credential. |
|
||||
| `DISCORD_SERVICE_TOKEN` | Required when the bot is enabled. Authenticates the Socket.IO service handshake and signs/verifies ingress envelopes. Treat as a high-entropy secret. |
|
||||
| `DISCORD_SERVICE_USER_ID` | Required when the bot is enabled. Provisioned Mosaic service principal used for ordinary Discord dispatch and attempted persistence; durable history is not guaranteed. |
|
||||
| `DISCORD_SERVICE_TENANT_ID` | Not required to start ordinary Discord chat, but required for the `/approve` and `/stop <approval>` control path. Use the provisioned tenant for the service boundary. |
|
||||
| `DISCORD_GATEWAY_URL` | Base gateway URL. The plugin connects to `${DISCORD_GATEWAY_URL}/chat`; the gateway factory default is `http://localhost:14242`. |
|
||||
| `DISCORD_GUILD_ID` | Optional guild ID used only by the current project-channel provisioning helper. It is not the message authorization allowlist. |
|
||||
| `DISCORD_ALLOWED_GUILD_IDS` | Required, comma-separated guild IDs. Empty or missing values fail closed during plugin creation. |
|
||||
| `DISCORD_ALLOWED_CHANNEL_IDS` | Required, comma-separated parent text-channel IDs. Thread messages are checked against their configured parent. |
|
||||
| `DISCORD_ALLOWED_USER_IDS` | Required, comma-separated Discord user IDs. This allowlist is checked in addition to `pairedUsers`. |
|
||||
| `DISCORD_INTERACTION_BINDINGS` | Required, non-empty JSON array of configuration-owned bindings. Malformed or empty data fails plugin creation. |
|
||||
| `DISCORD_MESSAGE_RATE_LIMIT_PER_MINUTE` | Optional positive integer; default is `30` authorized turns per guild/channel/user window. Zero, negative, and non-integer values are rejected. |
|
||||
| `DISCORD_THREAD_RATE_LIMIT_PER_MINUTE` | Optional positive integer; default is `5` mention-triggered thread routes per guild/channel/user window. Invalid values are rejected. |
|
||||
|
||||
`MOSAIC_AGENT_NAME` and `MOSAIC_AGENT_CONFIG_ID` are not substitutes for a Discord binding. The current Discord binding uses `instanceId` and `agentConfigId` inside `DISCORD_INTERACTION_BINDINGS`; do not invent a different environment-based routing contract.
|
||||
|
||||
### Binding shape
|
||||
|
||||
Use placeholders for identifiers and keep credentials out of the JSON:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"instanceId": "interaction-agent",
|
||||
"agentConfigId": "provisioned-agent-config-id",
|
||||
"guildId": "guild-id",
|
||||
"channelId": "parent-channel-id",
|
||||
"pairedUsers": {
|
||||
"discord-user-id": {
|
||||
"role": "operator",
|
||||
"mosaicUserId": "provisioned-mosaic-user-id"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
Each binding requires `instanceId`, `agentConfigId`, `guildId`, `channelId`, and a non-empty `pairedUsers` object. Pairing roles are `viewer`, `operator`, and `admin`. A role-only pairing remains accepted for ordinary non-privileged compatibility, but it has no `mosaicUserId` and cannot authorize the privileged approval/stop path. The guild and parent channel must also be present in their allowlists.
|
||||
|
||||
The bot needs permission to view and send messages in the configured channels and to create and send public threads. A category parent is not an authorization boundary. A thread inherits authorization only from its configured parent text channel.
|
||||
|
||||
### Secret handling
|
||||
|
||||
Supply `DISCORD_BOT_TOKEN` and `DISCORD_SERVICE_TOKEN` through the approved runtime secret mechanism. Do not commit them, put them in binding JSON, or pass them on a command line.
|
||||
|
||||
The current `mosaic gateway config --set KEY=VALUE` implementation writes the gateway `.env` file and prints the value in its confirmation; its mask list does not include `DISCORD_SERVICE_TOKEN`. Do **not** use that command for the service token. `mosaic gateway config --edit` exists for local configuration, but production secret provisioning must remain outside the repository and follow the approved secret path.
|
||||
|
||||
## Applying configuration safely
|
||||
|
||||
These are the current CLI commands exposed by `@mosaicstack/mosaic`; they manage the gateway daemon and do not constitute a Discord protocol:
|
||||
|
||||
```bash
|
||||
mosaic gateway install
|
||||
mosaic gateway config --edit
|
||||
mosaic gateway status
|
||||
mosaic gateway verify
|
||||
mosaic gateway restart
|
||||
mosaic gateway logs --lines 50
|
||||
```
|
||||
|
||||
The daemon reads its environment from `~/.config/mosaic/gateway/.env` by default; `MOSAIC_GATEWAY_HOME` can change that home. `mosaic gateway config --set KEY=VALUE` and `--unset KEY` are also implemented for non-secret values. After changing Discord configuration, restart the gateway so the plugin factory is rebuilt. `mosaic gateway status` and `mosaic gateway verify` check the gateway daemon/health surfaces; the current lifecycle host does not expose a channel-specific `healthAll` command, so a green gateway check alone is not proof that Discord is connected.
|
||||
|
||||
## Failure and abuse behavior
|
||||
|
||||
| Condition | Current result |
|
||||
| ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| Missing service token/user, allowlist, or interaction bindings when Discord is enabled | Gateway plugin creation fails rather than enabling an unconfigured remote-control surface. |
|
||||
| Invalid optional rate limit | Plugin creation fails; values must be positive integers. |
|
||||
| Unallowlisted guild/channel/user, unpaired user, or insufficient role | Message is ignored before thread creation and gateway dispatch. |
|
||||
| Mentioned message cannot create or fetch its requested thread | The message is not dispatched because its response target cannot be honored. |
|
||||
| Invalid HMAC, malformed envelope, route mismatch, wrong binding, or replayed native message ID | Gateway rejects the ingress without dispatch. |
|
||||
| Unsafe attachment metadata or URL | Gateway rejects the message before acknowledgement/dispatch. Current bounds include at most 10 attachments, HTTPS URLs without credentials, query strings, or fragments, and bounded ID/name/URL/metadata lengths. |
|
||||
| Missing `DISCORD_SERVICE_TENANT_ID` for approval/stop | The privileged control handler returns without creating or consuming an approval. |
|
||||
| Agent configuration ID does not resolve or its name differs from `instanceId` | Gateway refuses to create the Discord-bound session. |
|
||||
| External route cannot be persisted as a UUID conversation | Gateway may still dispatch live output; durable history and restart/resume continuity are not guaranteed and must not be inferred from delivery. |
|
||||
|
||||
## Explicitly not current
|
||||
|
||||
- **Telegram:** `TELEGRAM_BOT_TOKEN` and `TELEGRAM_GATEWAY_URL` can instantiate the raw legacy Telegram plugin, but that plugin does not use the shared channel DTOs, Discord-style service authentication, allowlists, pairing, route validation, or a tested gateway security boundary. Do not treat these variables as a secured Telegram equivalent of the Discord configuration above.
|
||||
- **Matrix:** No current gateway channel adapter, binding, authentication path, or focused channel test establishes Matrix ingress. Matrix-related fleet/runtime code is not evidence of a Matrix channel deployment procedure.
|
||||
- **Shared registry parity:** The current gateway `PLUGIN_REGISTRY` hosts lifecycle wrappers (`name`, `start`, `stop`, and optional project provisioning). It does not expose a universal channel health/ingress/egress registry. That is follow-up work, not an administrator capability today.
|
||||
|
||||
## Evidence
|
||||
|
||||
- [`plugins/discord/src/index.ts`](../../../plugins/discord/src/index.ts) — Discord allowlists, bindings, roles, thread routing, signed envelope, typed ingress/egress, limits, retry, and health.
|
||||
- [`plugins/discord/src/index.test.ts`](../../../plugins/discord/src/index.test.ts) — authorization ordering, thread behavior, attachments, stable routes, egress, rate limits, and health.
|
||||
- [`apps/gateway/src/chat/chat.gateway.ts`](../../../apps/gateway/src/chat/chat.gateway.ts) — `/chat` authentication, envelope validation, replay, trusted agent selection, ordinary dispatch, approval, and stop.
|
||||
- [`apps/gateway/src/chat/chat.gateway-auth.ts`](../../../apps/gateway/src/chat/chat.gateway-auth.ts) — timing-safe service-token and BetterAuth session validation.
|
||||
- [`apps/gateway/src/plugin/discord-ingress.security.spec.ts`](../../../apps/gateway/src/plugin/discord-ingress.security.spec.ts) — signature, allowlist, replay, attachment, binding, approval, stop, and logical-agent checks.
|
||||
- [`apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts`](../../../apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts) — control-flow evidence with explicit durable-session pre-enrollment, not proof of ordinary Discord persistence.
|
||||
- [`packages/mosaic/src/commands/gateway.ts`](../../../packages/mosaic/src/commands/gateway.ts) and [`gateway/config.ts`](../../../packages/mosaic/src/commands/gateway/config.ts) — verified gateway CLI command names and configuration behavior.
|
||||
- [Channel protocol architecture](../../DEVELOPER-GUIDE/architecture/channel-protocol.md) — canonical shared-contract and parity boundary.
|
||||
- [Discord conversation workflow](../../USER-GUIDE/workflows/discord-conversations.md) — end-user behavior.
|
||||
@@ -1,192 +0,0 @@
|
||||
---
|
||||
title: SSO Providers
|
||||
type: runbook
|
||||
audience: admin
|
||||
status: current
|
||||
source_of_truth: false
|
||||
---
|
||||
|
||||
# SSO Providers
|
||||
|
||||
Configure optional enterprise single sign-on for Mosaic Stack through Better Auth's generic OAuth integration. The gateway owns provider configuration and discovery; the web application renders only providers reported by the gateway.
|
||||
|
||||
> **Current behavior:** Authentik, WorkOS, and Keycloak are supported in the checked-in implementation. Authentik and WorkOS use OIDC. Keycloak supports OIDC and an optional direct SAML login URL. The web application does **not** read `NEXT_PUBLIC_WORKOS_ENABLED` or `NEXT_PUBLIC_KEYCLOAK_ENABLED`; provider buttons are discovered dynamically from the gateway.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before configuring a provider, establish these gateway settings:
|
||||
|
||||
- `BETTER_AUTH_URL` — the public base URL used to construct OAuth callback URLs.
|
||||
- `BETTER_AUTH_SECRET` — a strong secret for Better Auth sessions and tokens.
|
||||
- `GATEWAY_CORS_ORIGIN` — the web origin or comma-separated origins allowed by the gateway.
|
||||
|
||||
Keep client secrets and Better Auth secrets in the deployment secret store. Do not commit them to `.env` files or expose them to the web bundle.
|
||||
|
||||
## Provider configuration
|
||||
|
||||
### Authentik OIDC
|
||||
|
||||
Set all three variables to enable Authentik:
|
||||
|
||||
```bash
|
||||
AUTHENTIK_ISSUER=https://auth.example.com/application/o/mosaic
|
||||
AUTHENTIK_CLIENT_ID=...
|
||||
AUTHENTIK_CLIENT_SECRET=...
|
||||
```
|
||||
|
||||
The implementation derives OIDC discovery and endpoint URLs from `AUTHENTIK_ISSUER`. An optional team-claim label can be exposed in provider discovery:
|
||||
|
||||
```bash
|
||||
AUTHENTIK_TEAM_SYNC_CLAIM=groups
|
||||
```
|
||||
|
||||
The default reported claim is `groups`. The discovery payload reports this claim; verify any downstream membership-sync behavior separately before treating it as an authorization guarantee.
|
||||
|
||||
Register this redirect URI with the Authentik application:
|
||||
|
||||
```text
|
||||
{BETTER_AUTH_URL}/api/auth/oauth2/callback/authentik
|
||||
```
|
||||
|
||||
### WorkOS OIDC
|
||||
|
||||
Set all three variables to enable WorkOS:
|
||||
|
||||
```bash
|
||||
WORKOS_ISSUER=https://your-company.authkit.app
|
||||
WORKOS_CLIENT_ID=client_...
|
||||
WORKOS_CLIENT_SECRET=...
|
||||
```
|
||||
|
||||
Use the WorkOS AuthKit issuer or custom authentication domain, not a raw WorkOS REST API hostname. Mosaic derives the OIDC discovery URL by appending `/.well-known/openid-configuration` to the issuer. WorkOS uses PKCE and issuer validation in the current auth configuration.
|
||||
|
||||
An optional team-claim label can be exposed in provider discovery:
|
||||
|
||||
```bash
|
||||
WORKOS_TEAM_SYNC_CLAIM=organization_id
|
||||
```
|
||||
|
||||
The default reported claim is `organization_id`. The discovery payload reports this claim; verify any downstream membership-sync behavior separately before treating it as an authorization guarantee.
|
||||
|
||||
Register this redirect URI with the WorkOS application:
|
||||
|
||||
```text
|
||||
{BETTER_AUTH_URL}/api/auth/oauth2/callback/workos
|
||||
```
|
||||
|
||||
### Keycloak OIDC
|
||||
|
||||
Use either an explicit issuer or the URL-plus-realm form. The client ID and secret are required in both forms.
|
||||
|
||||
Explicit issuer:
|
||||
|
||||
```bash
|
||||
KEYCLOAK_ISSUER=https://auth.example.com/realms/mosaic
|
||||
KEYCLOAK_CLIENT_ID=mosaic
|
||||
KEYCLOAK_CLIENT_SECRET=...
|
||||
```
|
||||
|
||||
Derived issuer:
|
||||
|
||||
```bash
|
||||
KEYCLOAK_URL=https://auth.example.com
|
||||
KEYCLOAK_REALM=mosaic
|
||||
KEYCLOAK_CLIENT_ID=mosaic
|
||||
KEYCLOAK_CLIENT_SECRET=...
|
||||
```
|
||||
|
||||
`KEYCLOAK_ISSUER` takes precedence when both forms are present. Keycloak uses PKCE and issuer validation in the current auth configuration.
|
||||
|
||||
An optional team-claim label can be exposed in provider discovery:
|
||||
|
||||
```bash
|
||||
KEYCLOAK_TEAM_SYNC_CLAIM=groups
|
||||
```
|
||||
|
||||
The default reported claim is `groups`. The discovery payload reports this claim; verify any downstream membership-sync behavior separately before treating it as an authorization guarantee.
|
||||
|
||||
Register this redirect URI with the Keycloak client:
|
||||
|
||||
```text
|
||||
{BETTER_AUTH_URL}/api/auth/oauth2/callback/keycloak
|
||||
```
|
||||
|
||||
### Keycloak direct SAML fallback
|
||||
|
||||
The current web flow supports a direct SAML link for Keycloak when `KEYCLOAK_SAML_LOGIN_URL` is configured:
|
||||
|
||||
```bash
|
||||
KEYCLOAK_SAML_LOGIN_URL=https://auth.example.com/realms/mosaic/protocol/saml
|
||||
```
|
||||
|
||||
This creates a configured Keycloak provider with `loginMode: saml`. The web login button links directly to the supplied URL as `Continue with Keycloak (SAML)`; there is no Better Auth OIDC callback for this mode. The URL must be the provider's valid SAML launch URL for the deployment.
|
||||
|
||||
A SAML-only Keycloak configuration does not require the Keycloak OIDC client variables. Do not combine an incomplete OIDC variable set with SAML-only configuration: partial OIDC configuration is rejected during auth setup.
|
||||
|
||||
## Callback and discovery contract
|
||||
|
||||
Better Auth is mounted at `/api/auth`. OIDC callbacks use:
|
||||
|
||||
```text
|
||||
{BETTER_AUTH_URL}/api/auth/oauth2/callback/{providerId}
|
||||
```
|
||||
|
||||
The gateway exposes provider discovery at:
|
||||
|
||||
```text
|
||||
GET /api/sso/providers
|
||||
```
|
||||
|
||||
The response includes `authentik`, `workos`, and `keycloak` records with:
|
||||
|
||||
- `configured` — whether a usable OIDC or Keycloak SAML configuration is present.
|
||||
- `protocols` — supported protocols for the provider record.
|
||||
- `loginMode` — `oidc`, `saml`, or `null`.
|
||||
- `callbackPath` — the OIDC callback path, or `null` for SAML-only mode.
|
||||
- `teamSync` — the configured/default claim label exposed to the UI.
|
||||
- `samlFallback` — whether a direct Keycloak SAML URL is configured.
|
||||
- `warnings` — partial OIDC configuration warnings when reported.
|
||||
|
||||
The web login page filters this response to configured providers. OIDC buttons use Better Auth's `signIn.oauth2` flow. A configured Keycloak SAML fallback is rendered as a direct link. No provider-specific `NEXT_PUBLIC_*_ENABLED` flag is required or consumed.
|
||||
|
||||
## Configuration procedure
|
||||
|
||||
1. Set `BETTER_AUTH_URL` to the public gateway URL that the identity provider can reach.
|
||||
2. Set `BETTER_AUTH_SECRET` and the correct `GATEWAY_CORS_ORIGIN` values.
|
||||
3. Choose one provider configuration above and set its complete required variable group.
|
||||
4. Register the exact OIDC callback URI with the identity provider, when using OIDC.
|
||||
5. Restart or redeploy the gateway so it loads the changed environment.
|
||||
6. Inspect discovery without exposing secrets:
|
||||
|
||||
```bash
|
||||
curl "$BETTER_AUTH_URL/api/sso/providers"
|
||||
```
|
||||
|
||||
7. Open the web login page and confirm that only configured providers are shown.
|
||||
8. Complete a sign-in and verify the callback returns to the configured application.
|
||||
|
||||
## Partial configuration and failure modes
|
||||
|
||||
Provider configuration is optional. If no provider variables are set, the gateway can run without SSO providers and the web login page renders no SSO section.
|
||||
|
||||
For Authentik and WorkOS, setting only part of the issuer/client ID/client secret group raises a configuration error. For Keycloak OIDC, the client ID, client secret, and either an explicit issuer or a complete URL-plus-realm pair are required. Empty or whitespace-only values are treated as unset.
|
||||
|
||||
Common failures:
|
||||
|
||||
| Symptom | Check |
|
||||
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| Provider does not appear on the login page | Query `/api/sso/providers`; verify the complete provider variable group is present in the gateway environment. |
|
||||
| OAuth callback is rejected | Compare the registered redirect URI character-for-character with `BETTER_AUTH_URL` and the provider callback path. |
|
||||
| Provider is shown but sign-in cannot start | Check `loginMode`, issuer discovery, client credentials, and gateway logs. |
|
||||
| Keycloak SAML button is absent | Set `KEYCLOAK_SAML_LOGIN_URL` to the provider's direct launch URL and reload the gateway. |
|
||||
| Startup/auth initialization reports missing variables | Remove the partial provider configuration or provide the complete required group. |
|
||||
| SSO succeeds but team membership is unexpected | Treat `teamSync.claim` as discovery metadata and verify the actual claim mapping and membership-sync implementation. |
|
||||
|
||||
Do not enable a provider by adding the obsolete `NEXT_PUBLIC_WORKOS_ENABLED` or `NEXT_PUBLIC_KEYCLOAK_ENABLED` variables. They are not read by the current web application.
|
||||
|
||||
## Related
|
||||
|
||||
- [Administrator guide](../README.md)
|
||||
- [Security chapter](README.md)
|
||||
- [API documentation index](../../API/README.md)
|
||||
- [Documentation atlas](../../README.md)
|
||||
@@ -1,31 +0,0 @@
|
||||
# API Documentation
|
||||
|
||||
> **Status:** Scaffold only. The canonical gateway contract has not yet been migrated into this directory.
|
||||
|
||||
This directory is the single API documentation boundary. `OPENAPI.yaml` will be the machine-readable contract, and `ENDPOINTS.md` will provide the human-readable endpoint, authentication, permission, and error index. Neither file exists here yet; do not describe this scaffold as a complete API reference.
|
||||
|
||||
## Start here
|
||||
|
||||
- [Documentation atlas](../README.md) — placement rules and source-of-truth boundaries.
|
||||
- [Documentation sitemap](../SITEMAP.md) — current API transition status and authority-gated backlog.
|
||||
- [Documentation catalog audit](../reports/documentation/2026-08-10-docs-catalog-audit.md) — current API artifact inventory and migration evidence.
|
||||
|
||||
## Contract map
|
||||
|
||||
| Artifact | Purpose | Status |
|
||||
| ---------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------- |
|
||||
| `OPENAPI.yaml` | Canonical machine-readable HTTP/WebSocket API contract. | Planned; not present yet. |
|
||||
| `ENDPOINTS.md` | Human index for endpoint behavior, auth, permissions, and errors. | Planned; not present yet. |
|
||||
| [`../openapi-tess.yaml`](../openapi-tess.yaml) | Legacy Tess-scoped OpenAPI artifact with 17 paths. | Migration candidate; not the complete gateway contract. |
|
||||
|
||||
A contract migration must verify paths, schemas, authentication, permissions, error behavior, and generated/client references before the legacy artifact is retired. Keep scoped contracts explicitly labeled if they remain alongside the consolidated contract.
|
||||
|
||||
## Authoring boundary
|
||||
|
||||
New API contracts belong here. Use `OPENAPI.yaml` for machine-readable authority and `ENDPOINTS.md` for human-readable constraints that OpenAPI cannot fully express. Guide books may explain usage workflows, but must link back to this directory rather than copying endpoint definitions.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[DEVELOPER-GUIDE/architecture/README|Architecture index]]
|
||||
- [[ADMIN-GUIDE/security/README|SSO provider chapter]]
|
||||
@@ -1,50 +0,0 @@
|
||||
# Developer Guide
|
||||
|
||||
> **Status:** Partially migrated. Architecture, lease-broker verification, and channel-adapter authoring pages are current; other contributor chapters remain unmigrated.
|
||||
|
||||
This book is the canonical home for architecture, package and application guides, local development, testing, contribution workflow, and integration authoring. User-facing procedures belong in [`USER-GUIDE/`](../USER-GUIDE/); operator procedures belong in [`ADMIN-GUIDE/`](../ADMIN-GUIDE/); API contracts belong in [`API/`](../API/).
|
||||
|
||||
## Start here
|
||||
|
||||
- [Documentation atlas](../README.md) — placement rules and source-of-truth boundaries.
|
||||
- [Architecture index](architecture/README.md) — current architecture chapter scaffold.
|
||||
- [Documentation audit](../reports/documentation/2026-08-10-docs-catalog-audit.md) — evidence-based migration inventory.
|
||||
- [Product requirements](../PRD.md) — normative requirements, currently marked draft.
|
||||
|
||||
## Chapter map
|
||||
|
||||
| Chapter | Scope | Status |
|
||||
| ----------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------- |
|
||||
| [`architecture/`](architecture/README.md) | System model, components, data flow, security model, ADRs, and RFCs. | Partially migrated. |
|
||||
| `packages/` | Package- and application-level contracts and guides. | Scaffold only. |
|
||||
| `local-development/` | Safe local setup and development routes. | Scaffold only. |
|
||||
| `testing/` | Test strategy, verification, and quality gates. | Lease-broker verification boundary is current. |
|
||||
| `contributing/` | Contribution, review, and delivery workflow. | Scaffold only. |
|
||||
| `integrations/` | Plugin, provider, and adapter authoring. | Channel-adapter authoring boundary is current. |
|
||||
|
||||
### Current contributor pages
|
||||
|
||||
- [Lease-broker operations and verification](testing/lease-broker-operations.md) — safe static/test commands plus explicitly held live operations.
|
||||
- [Channel adapters](integrations/channel-adapters.md) — current shared contracts and Discord reference boundary; future adapter parity is draft.
|
||||
|
||||
Every promoted page must be added to this index and to [`SITEMAP.md`](../SITEMAP.md) in the same migration slice.
|
||||
|
||||
## Migration backlog — not current developer guidance
|
||||
|
||||
These are source candidates or stale records, not verified current instructions:
|
||||
|
||||
- [`archived TUI PRD`](../archive/tui/PRD-TUI_Improvements.md) — contradicted/stale; it references a missing `packages/cli`, while current TUI code is under `packages/mosaic`.
|
||||
- [`archived TUI task ledger`](../archive/tui/TASKS-TUI_Improvements.md) — historical task ledger; its status and worktree claims require revalidation.
|
||||
- `_old_structure/guides/dev-guide.md` — quarantined historical source; verify paths and commands before promotion. See the [documentation catalog](../reports/documentation/2026-08-10-docs-catalog-audit.md) for its disposition.
|
||||
|
||||
Do not make a legacy or archived page current by linking it from a chapter as if it were already promoted.
|
||||
|
||||
## Authoring boundary
|
||||
|
||||
New developer documentation belongs under one of the chapter directories above. Architecture decisions and RFCs must identify their status and authority; executable behavior must be checked against current code and tests.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[DEVELOPER-GUIDE/architecture/README|Architecture index]]
|
||||
- [[API/README|API index]]
|
||||
@@ -1,50 +0,0 @@
|
||||
# Architecture
|
||||
|
||||
> **Status:** Partially migrated. The lease-broker security-contract pages below are current references; the remaining architecture pages are still being classified.
|
||||
|
||||
This chapter is the canonical home for Mosaic Stack's system model, component boundaries, data and control flow, security model, architecture decisions, and RFCs. It explains why the system has its shape; it does not replace [`PRD.md`](../../PRD.md), [`TASKS.md`](../../TASKS.md), or the API contract.
|
||||
|
||||
## Promoted pages
|
||||
|
||||
- [`lease-broker-protocol.md`](lease-broker-protocol.md) — authenticated Unix-socket protocol, identity binding, framing, persistence, and lease transitions.
|
||||
- [`lease-broker-security.md`](lease-broker-security.md) — identity, ancestry, filesystem, whole-class, observer, and named residual security boundaries.
|
||||
- [`mutator-class-gate.md`](mutator-class-gate.md) — default-deny tool authorization, runtime adapters, launch choke point, and parser assurance boundary.
|
||||
- [`compaction-revocation.md`](compaction-revocation.md) — Claude/Pi observer lifecycle, runtime generations, revocation, and the bounded residual stale window.
|
||||
- [`channel-protocol.md`](channel-protocol.md) — current shared channel DTOs and Discord compatibility baseline, with unimplemented adapter work explicitly marked draft.
|
||||
- [`decisions/mos-runtime-portability-m1.md`](decisions/mos-runtime-portability-m1.md) — current logical identity, connector lease, grant, audit, and fencing decision; connector activation remains held.
|
||||
|
||||
These pages are current security-contract references and are consumed by the lease-broker acceptance suites. Their live deployment gaps remain explicitly labeled in the pages; this migration does not change runtime behavior.
|
||||
|
||||
## Planned pages
|
||||
|
||||
| Path | Purpose | Status |
|
||||
| ----------------------------------- | --------------------------------------------------------------------- | ------------------------- |
|
||||
| `system-overview.md` | Platform boundary and major request, event, and agent-runtime flows. | Planned. |
|
||||
| `component-map.md` | Apps, packages, plugins, and dependency ownership. | Planned. |
|
||||
| `data-flow.md` | Data, event, and control-plane movement. | Planned. |
|
||||
| `security-model.md` | Trust boundaries, authority, authentication, and authorization model. | Planned. |
|
||||
| [`decisions/`](decisions/README.md) | Approved architecture decision records. | Partially migrated. |
|
||||
| [`rfcs/`](rfcs/README.md) | Proposals and protocol RFCs. | Draft egress RFC indexed. |
|
||||
|
||||
### Draft RFCs
|
||||
|
||||
- [`rfcs/optional-ai-egress-gateways.md`](rfcs/optional-ai-egress-gateways.md) — proposed model-egress boundary; not approved or integrated.
|
||||
|
||||
Promoted pages must be linked here, from [`DEVELOPER-GUIDE/README.md`](../README.md), and from [`SITEMAP.md`](../../SITEMAP.md). Do not create duplicate architecture pages in `docs/mosaic-stack/` or the docs root.
|
||||
|
||||
## Migration backlog — not current architecture
|
||||
|
||||
- [`docs/README.md`](../../README.md) — current documentation contract and placement rules.
|
||||
- [`Documentation information architecture design`](../../plans/2026-08-10-docs-information-architecture-design.md) — approved documentation structure decision, not product architecture.
|
||||
- [`Documentation catalog audit`](../../reports/documentation/2026-08-10-docs-catalog-audit.md) — evidence and migration recommendations, not normative architecture.
|
||||
|
||||
## Source-of-truth boundary
|
||||
|
||||
Architecture pages explain approved design and current system boundaries. Requirements remain in [`PRD.md`](../../PRD.md); active work remains in [`TASKS.md`](../../TASKS.md); executable behavior remains authoritative in source and tests. Draft proposals belong in `rfcs/` or [`docs/plans/`](../../plans/), with status clearly labeled.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[DEVELOPER-GUIDE/README|Developer guide]]
|
||||
- [[PRD|Product requirements]]
|
||||
- [[API/README|API index]]
|
||||
@@ -1,285 +0,0 @@
|
||||
# Channel protocol architecture
|
||||
|
||||
> **Status:** Current shared type contract and Discord compatibility baseline. The shared gateway registry, Telegram parity, Matrix integration, identity-linking, and multi-surface multiplexing described below are draft or unimplemented.
|
||||
>
|
||||
> **Audience:** Developers maintaining `@mosaicstack/types`, channel plugins, the gateway chat/plugin boundaries, or future official adapters.
|
||||
>
|
||||
> **Last verified:** 2026-08-10 against the source and focused tests listed in [Evidence](#evidence).
|
||||
>
|
||||
> **Authority:** Executable source and tests are authoritative for current behavior. This page explains the boundary; it is not a runtime registry, an API contract, a requirements document, or proof that every channel uses the shared DTOs.
|
||||
|
||||
## Reading this page
|
||||
|
||||
This page intentionally separates three states:
|
||||
|
||||
- **Current** — implemented in the repository and supported by the cited tests.
|
||||
- **Compatibility** — an existing wire path that preserves current behavior but does not yet mean that the shared channel ports are wired through the gateway.
|
||||
- **Draft** — a design direction or follow-up work item. Draft sections have no implementation authority and must not be used as instructions for operating Telegram, Matrix, identity linking, or cross-surface fanout.
|
||||
|
||||
The migration from `docs/_old_structure/architecture/channel-protocol.md` is a documentation correction. It does not add adapters, change gateway behavior, change authentication, or create database objects.
|
||||
|
||||
## Authority and evidence boundaries
|
||||
|
||||
| Boundary | Current authority | What this page may claim |
|
||||
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Shared channel types and ports | [`channel.dto.ts`](../../../packages/types/src/channel/channel.dto.ts), [`channel-adapter.ts`](../../../packages/types/src/channel/channel-adapter.ts), and their exports | The TypeScript shapes and method signatures that are currently published from `@mosaicstack/types`. |
|
||||
| Discord native behavior | [`plugins/discord/src/index.ts`](../../../plugins/discord/src/index.ts) and [`index.test.ts`](../../../plugins/discord/src/index.test.ts) | The Discord allowlist, pairing, role, thread, ingress, egress, retry, and health behavior covered by source and tests. |
|
||||
| Discord gateway compatibility | [`chat.gateway.ts`](../../../apps/gateway/src/chat/chat.gateway.ts), [`chat.gateway-auth.ts`](../../../apps/gateway/src/chat/chat.gateway-auth.ts), and the focused gateway tests | The signed Socket.IO service path, gateway validation, raw chat events, and current session dispatch behavior. |
|
||||
| Plugin hosting | [`plugin.interface.ts`](../../../apps/gateway/src/plugin/plugin.interface.ts), [`plugin.module.ts`](../../../apps/gateway/src/plugin/plugin.module.ts), and [`plugin.service.ts`](../../../apps/gateway/src/plugin/plugin.service.ts) | The lifecycle registry that exists today. It is not evidence of a shared `OfficialChannelAdapter` registry. |
|
||||
| Telegram | [`plugins/telegram/src/index.ts`](../../../plugins/telegram/src/index.ts) and [`package.json`](../../../plugins/telegram/package.json) | The raw legacy behavior that exists. It is not evidence of shared-contract parity or a working authenticated gateway integration. |
|
||||
| Matrix, identity linking, and multiplexing | No matching current implementation and test boundary was found for the old page's designs | These topics remain explicitly draft/unimplemented here. |
|
||||
|
||||
The current source boundaries also distinguish two identities:
|
||||
|
||||
1. A channel route carries a configuration-owned logical agent and response destination.
|
||||
2. The gateway chooses provider, model, and runtime session internally. Durable-session enrollment is separate and is not proven by the external channel route alone.
|
||||
|
||||
A route is therefore not a claim that a channel adapter owns or exposes a harness, provider, model, process, or native runtime-session identity.
|
||||
|
||||
## Current shared contract
|
||||
|
||||
The channel types are exported through `packages/types/src/channel/index.ts` and `packages/types/src/index.ts`. They define a transport-neutral vocabulary, but TypeScript interfaces alone do not prove that every producer or consumer uses that vocabulary.
|
||||
|
||||
### DTOs
|
||||
|
||||
The current DTO surface is:
|
||||
|
||||
| Type | Current shape and boundary |
|
||||
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `ChannelMetadataValue` | JSON-safe strings, numbers, booleans, `null`, arrays, and nested objects. |
|
||||
| `ChannelAttachmentDto` | `id`, `name`, `mimeType`, `url`, and optional `sizeBytes`. |
|
||||
| `ChannelMessageDto` | `id`, `channelName`, `channelId`, `senderId`, `senderKind`, `content`, `contentKind`, `timestamp`, and `metadata`; `threadId`, `replyToId`, and `attachments` are optional. |
|
||||
| `ChannelAuthorizedPrincipalDto` | Native `channelUserId`, a `viewer`/`operator`/`admin` role, and an optional `mosaicUserId` for privileged gateway policy. |
|
||||
| `ChannelBindingDto` | Configuration-owned `bindingId`, `channelName`, `workspaceId`, `channelId`, `logicalAgentId`, and paired `principals`. Credentials are intentionally absent. |
|
||||
| `ChannelResponseTargetDto` | `channelId` and an optional `threadId`. |
|
||||
| `ChannelConversationRouteDto` | `bindingId`, `logicalAgentId`, `conversationId`, `channelName`, `authorizationChannelId`, and `responseTarget`. |
|
||||
| `ChannelIngressDto` | `correlationId`, `nativeMessageId`, an operation, an authorized principal, a normalized message, and a stable route. |
|
||||
| `ChannelEgressDto` | `correlationId`, a normalized message, and the stable route. |
|
||||
| `ChannelAdapterHealthDto` | `status` of `connected`, `degraded`, or `disconnected`, with optional `detail`. |
|
||||
|
||||
The available operations are `message.send`, `approval.create`, and `session.stop`. The available sender kinds are `user`, `agent`, and `system`; content kinds are `text`, `markdown`, `code`, `image`, and `file`.
|
||||
|
||||
### Lifecycle and ports
|
||||
|
||||
The shared adapter file currently defines these seams:
|
||||
|
||||
```typescript
|
||||
interface OfficialChannelAdapter {
|
||||
readonly name: string;
|
||||
start(): Promise<void>;
|
||||
stop(): Promise<void>;
|
||||
health(): Promise<ChannelAdapterHealthDto>;
|
||||
}
|
||||
|
||||
interface ChannelIngressPort {
|
||||
receive(ingress: ChannelIngressDto): Promise<void>;
|
||||
}
|
||||
|
||||
interface ChannelEgressPort {
|
||||
send(egress: ChannelEgressDto): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
`ChannelDeliveryError` currently has only these codes: `invalid_route`, `destination_unavailable`, and `delivery_failed`. The type surface does not define a revoked-auth error code or an executable protocol version `1.0.0`.
|
||||
|
||||
### Stable route rule
|
||||
|
||||
`ChannelConversationRouteDto` deliberately omits provider, harness, model, process, and native runtime-session fields. The Discord implementation derives its current conversation address as:
|
||||
|
||||
```text
|
||||
<logical-agent-id>:discord:<response-channel-id>
|
||||
```
|
||||
|
||||
and derives its binding address from the configured guild, parent channel, and logical-agent instance. The gateway validates the expected Discord conversation address before dispatch. This is a route-integrity rule, not a claim that the shared DTO is already the gateway's universal session API.
|
||||
|
||||
### What is and is not wired today
|
||||
|
||||
The Discord class implements both `OfficialChannelAdapter` and `ChannelEgressPort`, and accepts an optional `ChannelIngressPort` dependency. The direct ingress seam is exercised by the Discord tests. However, the gateway host currently registers `IChannelPlugin` objects with only `name`, `start`, `stop`, and optional project provisioning. Its `PLUGIN_REGISTRY` is an array of those lifecycle wrappers; it does not expose `health()`, `ChannelRegistry.healthAll()`, or shared port wiring.
|
||||
|
||||
The gateway's current output path is also still Socket.IO event streaming (`agent:start`, `agent:text`, and `agent:end`). No gateway service in the cited implementation produces a `ChannelEgressDto` for a registered adapter. The shared ports are therefore current contracts and a tested Discord seam, not a completed gateway-wide adapter architecture.
|
||||
|
||||
## Current Discord compatibility path
|
||||
|
||||
Discord is the current reference implementation for the shared contract and the compatibility path. Its behavior is split between native Discord translation in the plugin and gateway-side validation/dispatch.
|
||||
|
||||
### Native ingress and authorization
|
||||
|
||||
For an inbound Discord message, the plugin currently:
|
||||
|
||||
1. Ignores bot-authored messages and messages without a guild.
|
||||
2. Uses the configured parent text channel as the authorization channel only when the message is in a thread. A normal channel's category parent is not substituted for the channel itself.
|
||||
3. Applies default-deny guild, channel, and user allowlists.
|
||||
4. Resolves a configuration-owned binding and paired user role before creating a thread or dispatching to the gateway. `viewer` cannot send turns; approval and stop are admin operations.
|
||||
5. Applies per-user/channel message and mention-thread rate limits before Discord thread creation or gateway dispatch.
|
||||
6. Builds a stable route from the configured logical-agent instance and the response channel/thread.
|
||||
7. Normalizes the authorized turn to `ChannelIngressDto` when a direct `ingressPort` dependency is supplied.
|
||||
|
||||
The normalized `ChannelMessageDto` currently includes:
|
||||
|
||||
- `channelName: "discord"`;
|
||||
- the response channel as `channelId`;
|
||||
- the Discord author as `senderId` and `senderKind: "user"`;
|
||||
- `markdown` for non-empty text, or `image`/`file` for attachment-only input;
|
||||
- attachments mapped to `ChannelAttachmentDto`; and
|
||||
- `metadata` containing `channelMessageId` and `guildId`.
|
||||
|
||||
The implementation does **not** currently populate `channelType`, mentions, embeds, or `replyToId` in that normalized metadata. The old page's broader Discord metadata table must not be treated as current behavior.
|
||||
|
||||
### Direct shared ingress versus compatibility envelope
|
||||
|
||||
When a direct port is present, the plugin calls `ChannelIngressPort.receive()` with the complete normalized ingress DTO. In the current gateway-hosted path, the plugin instead signs a compatibility envelope and emits one of these Socket.IO events:
|
||||
|
||||
| Shared operation | Compatibility event | Current envelope boundary |
|
||||
| ----------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `message.send` | `message` | Correlation ID, native Discord message ID, guild/channel/user IDs, conversation ID, content, optional thread ID, and attachments. |
|
||||
| `approval.create` | `discord:approve` | The same signed Discord identity and route fields, carrying the approval command. |
|
||||
| `session.stop` | `discord:stop` | The same signed Discord identity and route fields, carrying the stop command. |
|
||||
|
||||
The signature is HMAC-SHA-256 over the ordered envelope payload using the injected Discord service token. The token is used for service authentication and is not part of the protocol payload.
|
||||
|
||||
### Gateway validation and dispatch
|
||||
|
||||
The gateway exposes the `/chat` Socket.IO namespace. A Discord connection authenticates with `discordServiceToken`; ordinary clients use a BetterAuth session. For Discord service messages, the gateway:
|
||||
|
||||
1. Verifies the signed envelope with `DISCORD_SERVICE_TOKEN`.
|
||||
2. Re-applies the configured guild, channel, and user allowlists.
|
||||
3. Resolves the configured binding and operation role.
|
||||
4. Checks that the conversation ID matches the bound logical-agent instance and channel/thread.
|
||||
5. Rejects a repeated native Discord message ID through the bounded replay protector.
|
||||
6. Reconstructs a gateway `ChatSocketMessageDto` containing the conversation ID, content, and validated attachments.
|
||||
7. Uses the configured Discord service principal/tenant for ordinary chat dispatch and the paired `mosaicUserId` for privileged approval/stop policy where required.
|
||||
8. Selects the trusted `agentConfigId` from the binding and verifies that the provisioned agent name matches the binding's logical-agent instance.
|
||||
|
||||
This path is intentionally described as compatibility: the gateway receives a signed Discord envelope and reconstructs chat input; it does not currently receive a complete `ChannelIngressDto` from the host registry.
|
||||
|
||||
### Persistence and durability boundary
|
||||
|
||||
The Discord `conversationId` is an external route string such as `<logical-agent-id>:discord:<channel-or-thread-id>`. Persisted conversations and messages use UUID conversation IDs. No current route-mapping layer was found that resolves the external route to a generated UUID before ordinary Discord writes. The gateway catches persistence/binding failures and may continue dispatch, so live output does not prove durable history or restart/resume continuity.
|
||||
|
||||
The focused cross-surface integration test explicitly pre-enrolls a durable session before exercising control flow. It does not prove that a fresh ordinary Discord message creates durable conversation/message rows. Current architecture claims are therefore limited to authenticated routing and live delivery. Durable Discord continuity requires a route-to-UUID mapping, observable persistence failures, ordinary-ingress enrollment where required, and a fresh-database restart test.
|
||||
|
||||
### Thread and conversation behavior
|
||||
|
||||
| Inbound case | Current route and side effect |
|
||||
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Authorized untagged message in a parent channel | Uses the parent channel as the response target; no thread is created. |
|
||||
| Authorized bot mention in a parent channel | Creates a public thread, or reuses the thread already attached to that message, and routes the response to that thread. |
|
||||
| Authorized follow-up in an existing thread | Authorizes against the configured parent channel and keeps the existing thread; it does not create a nested thread. |
|
||||
| `/approve` or `/stop <approval>` | Uses the current parent/thread route and requires an already enrolled durable session; ordinary chat does not prove enrollment. |
|
||||
| Requested thread creation fails | Does not dispatch the message, because the requested response target cannot be honored. |
|
||||
|
||||
### Discord egress and health
|
||||
|
||||
`DiscordPlugin.send()` is a typed egress implementation, even though the current gateway does not wire it as a universal `ChannelEgressPort`. It:
|
||||
|
||||
- rejects a forged or route-misaligned conversation before looking up a Discord destination;
|
||||
- rejects a missing destination with `destination_unavailable`;
|
||||
- chunks text at a Discord-safe 1,900-character boundary;
|
||||
- retries transient rate-limit, server, and network failures up to three attempts;
|
||||
- derives one stable nonce per correlation/chunk and sends with Discord's enforced nonce option; and
|
||||
- does not retry permanent delivery failures.
|
||||
|
||||
The plugin reports `connected`, `degraded`, or `disconnected` from Discord client readiness and gateway socket connectivity. The health method is tested without exposing provider or runtime state. Outbound delivery uses Discord's native send operation; code-content wrapping from the former page is not implemented.
|
||||
|
||||
Agent output reaches the plugin through the current `agent:start`/`agent:text`/`agent:end` Socket.IO events. The plugin buffers the text by conversation ID and calls its typed Discord egress method when the stream ends.
|
||||
|
||||
## Draft: shared adapter registry and gateway wiring
|
||||
|
||||
**Status: Draft / unimplemented.**
|
||||
|
||||
The gateway does have a startup `IChannelPlugin[]` registry, but that registry is a lifecycle host for the current Discord and Telegram wrappers. It does not register `OfficialChannelAdapter` instances, inject `ChannelIngressPort` and `ChannelEgressPort` through a common gateway service, expose adapter health, or implement a dynamic `ChannelRegistry` with `getAdapter`, `listAdapters`, and `healthAll` semantics.
|
||||
|
||||
The former page's claim that adapters are already registered uniformly, or that new adapters can be added without channel-specific gateway branches, is not current. The gateway still has Discord-specific authentication, envelope, approval, stop, replay, and binding branches.
|
||||
|
||||
A future implementation may define a registry and host lifecycle, but that work must first specify:
|
||||
|
||||
- ownership and injection of ingress and egress ports;
|
||||
- health and failure semantics;
|
||||
- binding and credential loading boundaries;
|
||||
- compatibility behavior for existing Socket.IO clients; and
|
||||
- tests proving that an adapter cannot bypass gateway authorization or route validation.
|
||||
|
||||
Until then, this section is design context only.
|
||||
|
||||
## Draft: Telegram shared-contract parity
|
||||
|
||||
**Status: Raw legacy adapter exists; shared protocol parity and authenticated gateway participation are unimplemented/unproven.**
|
||||
|
||||
The current Telegram plugin is not an `OfficialChannelAdapter` implementation. Its source currently:
|
||||
|
||||
- launches a Telegraf bot and a Socket.IO client;
|
||||
- accepts only messages with a text field and ignores attachment-only messages;
|
||||
- maps each Telegram chat ID to `telegram-<chatId>`;
|
||||
- emits a raw `{ conversationId, content, role: "user" }` object rather than `ChannelIngressDto`;
|
||||
- has no shared DTO import, channel binding, principal/role policy, native message ID, attachment mapping, route validation, or health method; and
|
||||
- sends plain `sendMessage` responses in chunks, without the former page's claimed MarkdownV2, photo, or document handling.
|
||||
|
||||
The Telegram Socket.IO client does not provide the Discord service token or a BetterAuth session in its connection options. The source therefore does not establish participation in the gateway's current authenticated connection path. The package's test script uses `--passWithNoTests`, and no package test file is present in this checkout.
|
||||
|
||||
Future Telegram parity is draft work. It would need an explicit identity/authentication boundary, shared ingress normalization, binding and operation policy, route-safe egress, health reporting, and focused tests before this page could describe Telegram as an official shared-contract adapter.
|
||||
|
||||
## Draft: Matrix integration
|
||||
|
||||
**Status: Draft / unimplemented in the channel protocol.**
|
||||
|
||||
No current gateway adapter, shared-port wiring, channel binding, identity resolver, room/conversation persistence boundary, or focused channel tests were found for the Matrix design described by the former page. The old Conduit choice, appservice registration, room and Space mappings, ghost users, encryption defaults, retention jobs, and agent-room behavior are therefore proposals, not current system behavior.
|
||||
|
||||
Those details must not be copied into implementation instructions or treated as deployment requirements. A future Matrix effort must independently decide and implement its homeserver/appservice boundary, authentication, route mapping, persistence, authorization, delivery, and tests.
|
||||
|
||||
## Draft: channel identity linking
|
||||
|
||||
**Status: Draft / unimplemented.**
|
||||
|
||||
The shared contract carries an already-authorized `ChannelAuthorizedPrincipalDto`; it does not implement a generic channel-identity database or linking flow. Discord currently uses configuration-owned allowlists and pairings. A pairing may include a `mosaicUserId` for privileged operations, while ordinary Discord chat dispatch uses the configured service principal and tenant in the gateway.
|
||||
|
||||
No current evidence establishes the former page's proposed `channel_identities` table, OAuth/deep-link flow, anonymous-principal behavior, persistent Matrix session, or revocation endpoint. Those are not implied by the optional `mosaicUserId` field and must remain planned work until schema, auth, gateway, and adapter implementations exist together.
|
||||
|
||||
## Draft: multi-surface conversation multiplexing
|
||||
|
||||
**Status: Partial raw chat-session support exists; the proposed channel-protocol fanout architecture is unimplemented.**
|
||||
|
||||
The gateway currently tracks client/conversation sessions and emits raw typed Socket.IO chat events. Focused gateway tests verify isolation of concurrent conversation streams sharing one socket. The chat event contract is `ChatMessagePayload` plus `agent:*` events, not `ChannelMessageDto` fanout.
|
||||
|
||||
There is no evidence in the cited current path for the former page's complete `ConversationService` plus Valkey pub/sub topology, canonical cross-surface `ChannelMessageDto` persistence, or Matrix fanout. Concurrent stream isolation must not be presented as multi-surface channel multiplexing.
|
||||
|
||||
A future multiplexing design must define canonical message ownership, subscription and fanout boundaries, replay/ordering behavior, conflict semantics, and per-surface authorization before it can become architecture guidance.
|
||||
|
||||
## Current limitations and version boundary
|
||||
|
||||
The following are intentionally not claimed as current protocol policy:
|
||||
|
||||
- A semantic protocol version of `1.0.0`. `packages/types/package.json` currently reports package version `0.0.2`, while `packages/types/src/index.ts` exports `VERSION = "0.0.0"`; no migration machinery is present in the cited channel code.
|
||||
- A generic revoked-auth `ChannelDeliveryError` code. The current union contains only `invalid_route`, `destination_unavailable`, and `delivery_failed`.
|
||||
- Structured log records with a universal `{ channel, event, ... }` schema. Current plugin logs are string-prefixed.
|
||||
- Universal adapter health monitoring by the gateway host. Discord exposes health; the `IChannelPlugin` host does not.
|
||||
- Complete `ChannelEgressDto` delivery from the gateway to every channel. Discord's current gateway egress remains Socket.IO stream events followed by plugin-side delivery.
|
||||
|
||||
These limitations are evidence boundaries, not requests to change implementation in this documentation migration.
|
||||
|
||||
## Evidence
|
||||
|
||||
Current-contract evidence:
|
||||
|
||||
- [`packages/types/src/channel/channel.dto.ts`](../../../packages/types/src/channel/channel.dto.ts) — DTOs, enums, route fields, and metadata shape.
|
||||
- [`packages/types/src/channel/channel-adapter.ts`](../../../packages/types/src/channel/channel-adapter.ts) — adapter lifecycle, ingress/egress ports, and delivery errors.
|
||||
- [`packages/types/src/channel/index.ts`](../../../packages/types/src/channel/index.ts) and [`packages/types/src/index.ts`](../../../packages/types/src/index.ts) — export surface and current package `VERSION`.
|
||||
|
||||
Discord evidence:
|
||||
|
||||
- [`plugins/discord/src/index.ts`](../../../plugins/discord/src/index.ts) — native translation, authorization, thread routing, signed compatibility envelope, typed ingress/egress seam, retry, and health.
|
||||
- [`plugins/discord/src/index.test.ts`](../../../plugins/discord/src/index.test.ts) — direct ingress, routing/thread behavior, authorization ordering, attachments, route-safe egress, retries, chunking, and health.
|
||||
- [`apps/gateway/src/chat/chat.gateway.ts`](../../../apps/gateway/src/chat/chat.gateway.ts) — `/chat` namespace, service/session authentication, signed-envelope reconstruction, trusted binding selection, and raw stream egress.
|
||||
- [`apps/gateway/src/chat/chat.gateway-auth.ts`](../../../apps/gateway/src/chat/chat.gateway-auth.ts) — Discord service-token and BetterAuth session validation.
|
||||
- [`apps/gateway/src/plugin/discord-ingress.security.spec.ts`](../../../apps/gateway/src/plugin/discord-ingress.security.spec.ts) — signature, allowlist, replay, binding, attachment, approval, stop, and logical-agent checks.
|
||||
- [`apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts`](../../../apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts) — focused control-flow test with explicit durable-session pre-enrollment; not ordinary persistence evidence.
|
||||
|
||||
Hosting and compatibility evidence:
|
||||
|
||||
- [`apps/gateway/src/plugin/plugin.interface.ts`](../../../apps/gateway/src/plugin/plugin.interface.ts), [`plugin.module.ts`](../../../apps/gateway/src/plugin/plugin.module.ts), and [`plugin.service.ts`](../../../apps/gateway/src/plugin/plugin.service.ts) — current lifecycle-only plugin host.
|
||||
- [`packages/types/src/chat/events.ts`](../../../packages/types/src/chat/events.ts) — raw Socket.IO chat event contracts.
|
||||
- [`apps/gateway/src/chat/chat.gateway-redaction.spec.ts`](../../../apps/gateway/src/chat/chat.gateway-redaction.spec.ts) — current per-client/per-conversation stream isolation evidence.
|
||||
|
||||
Telegram evidence:
|
||||
|
||||
- [`plugins/telegram/src/index.ts`](../../../plugins/telegram/src/index.ts) — current raw Telegraf and Socket.IO behavior.
|
||||
- [`plugins/telegram/package.json`](../../../plugins/telegram/package.json) — package scripts, including `--passWithNoTests`.
|
||||
@@ -1,15 +0,0 @@
|
||||
# Architecture Decisions
|
||||
|
||||
> **Status:** Current decision index. A decision describes an implemented and accepted boundary; draft proposals belong under `rfcs/` or `docs/plans/`.
|
||||
|
||||
## Current decisions
|
||||
|
||||
- [Mos runtime portability M1 — logical identity and fencing](mos-runtime-portability-m1.md) — implemented lease, grant, audit, policy, and fencing boundary; connector activation remains held.
|
||||
|
||||
Decision pages do not override product requirements, API contracts, or executable behavior. Each page must identify implementation evidence, operational status, and explicit non-goals.
|
||||
|
||||
## Related
|
||||
|
||||
- [[DEVELOPER-GUIDE/architecture/README|Architecture index]]
|
||||
- [[PRD|Product requirements]]
|
||||
- [[ADMIN-GUIDE/operations/mos-connector-lease-operations|Held connector lease operations]]
|
||||
@@ -1,96 +0,0 @@
|
||||
# Mos Runtime Portability M1 — Logical Identity and Fencing
|
||||
|
||||
> **Decision status:** Current implemented decision (M1).
|
||||
> **Operational status:** The lease/fencing boundary is implemented and test-covered; connector activation remains held.
|
||||
> **Audience:** Mosaic developers, gateway/runtime adapter authors, and security reviewers.
|
||||
> **Authority:** This page records the current M1 boundary. The executable source and tests are authoritative for behavior; [`PRD.md`](../../../PRD.md) remains authoritative for requirements.
|
||||
|
||||
## Decision
|
||||
|
||||
M1 separates the logical Mosaic agent from any Claude, Pi, Codex, tmux, Matrix, or provider-native session. The core identity is:
|
||||
|
||||
```text
|
||||
(tenant_id, logical_agent_id, binding_id)
|
||||
```
|
||||
|
||||
`logical_agent_id` is a Mosaic logical identifier, not a runtime session identifier. The gateway derives the tenant from authenticated actor scope. The current internal service boundary normalizes the supplied logical-agent identifier and binding; a future public boundary must resolve and authorize those values server-side. Runtime-native session IDs are not part of the lease or execution-grant contract.
|
||||
|
||||
A connector is a replaceable holder of authority for one logical binding. It is not the logical agent identity.
|
||||
|
||||
## Durable lease model
|
||||
|
||||
The additive migration creates `logical_agent_connector_leases` with one unique row per tenant/logical-agent/binding tuple. The current row contains:
|
||||
|
||||
- an opaque lease UUID;
|
||||
- connector ID and normalized allowed scopes;
|
||||
- a positive decimal fencing epoch exposed by the application and stored as PostgreSQL `bigint`;
|
||||
- acquisition, heartbeat, expiry, release, and update timestamps.
|
||||
|
||||
Initial acquisition is insert-only. An existing active row yields `lease_held`. An expired or released row yields `takeover_required`; ordinary acquisition does not recover it. An authorized takeover compares and swaps the expected epoch, rotates the lease UUID, and increments the epoch atomically. Heartbeat and release match the full identity, binding, connector, lease UUID, and epoch.
|
||||
|
||||
### Audit and enforcement precision
|
||||
|
||||
`connector_lease_audit_log` is an **application-level append-only contract**: the repository has an insert-only audit path and writes credential-safe lifecycle/rejection metadata. The checked-in schema and migration add a table and indexes, but do not add database triggers, permissions, or other database-level protection against `UPDATE` or `DELETE`. M1 therefore does not claim database-enforced immutability; an append-only guarantee at the database security boundary is a later hardening requirement.
|
||||
|
||||
Likewise, identifier, scope, and epoch normalization is performed at the application boundary by the shared types/coordinator and gateway service. The database enforces column types, non-null fields, the lease primary key, and the unique tenant/logical-agent/binding index, but it does not independently enforce all application formats or semantics such as positive epochs, canonical scope ordering/deduplication, or constrained identifier patterns. Database shape must not be mistaken for a second normalization layer.
|
||||
|
||||
## Execution grants and TTL boundaries
|
||||
|
||||
`ConnectorLeaseCoordinator` issues a short-lived internal grant only after rereading the durable current lease. It enforces hard defense-in-depth maxima of five minutes for leases and thirty seconds for grants; constructor options may only tighten those limits. A grant is bound to tenant, logical agent, binding, connector, lease UUID, scope subset, expiry, correlation ID, and epoch.
|
||||
|
||||
The gateway policy and coordinator have deliberately separate TTL responsibilities:
|
||||
|
||||
- `ConnectorLeaseService` passes the request's numeric `ttlMs` to policy as `requestedTtlMs` for acquire, takeover, heartbeat, and grant issuance. Identity and scopes are normalized before policy evaluation, but this TTL is a request input, not a coordinator-normalized or effective TTL.
|
||||
- Release and read policy checks use `null` because they do not request a TTL.
|
||||
- After policy authorization, the coordinator validates the TTL as a positive safe integer and rejects values above the applicable hard cap (`300000ms` for leases or `30000ms` for grants). It does not silently clamp an over-cap value.
|
||||
- A policy may impose a stricter duration limit, but it cannot expand the coordinator cap. A policy implementation must validate the requested value itself if its decision depends on a bounded or canonical TTL.
|
||||
|
||||
Grant validation occurs immediately before adapter invocation and rereads the durable current row. Validation denies:
|
||||
|
||||
- grants not minted by the current gateway process, including cloned or forged objects;
|
||||
- expired grants or leases;
|
||||
- released leases;
|
||||
- stale epochs or replaced connectors/lease UUIDs;
|
||||
- missing, cross-tenant, cross-agent, or cross-binding leases; and
|
||||
- scopes not authorized by both the grant and the current lease.
|
||||
|
||||
A gateway restart intentionally invalidates process-local grant provenance. The durable lease and epoch survive, but a fresh grant is required after current-lease and policy validation.
|
||||
|
||||
## Adapter boundary and activation state
|
||||
|
||||
The normalized `ConnectorExecutionContext` and `FencedConnectorAdapter` contract define the future adapter boundary. When a concrete adapter is activated, it must receive the context only after the coordinator's final validation and must propagate the epoch/context to downstream effect boundaries that need to fence races after gateway validation.
|
||||
|
||||
That contract is **not evidence of an activated adapter**. The current production module registers the lease repository, service, and deny-all policy. The coordinator and gateway integration tests use test adapters, but current production runtime providers and channel paths do not consume `ConnectorExecutionContext` or call `executeGrant`. No concrete Claude, Pi, Codex, Matrix, tmux, provider, or channel connector is activated by M1.
|
||||
|
||||
`ConnectorLeaseService` is the gateway-owned policy surface. It derives tenant scope from authenticated context, records policy denials, and is internal: no M1 connector-lease HTTP controller or administration endpoint is registered. The default `DenyConnectorLeasePolicy` rejects every lease and grant operation until a separately authorized server-side policy is supplied.
|
||||
|
||||
## Current implementation evidence
|
||||
|
||||
The current boundary is represented by the following checked-in surfaces:
|
||||
|
||||
- Contract and application normalizers: `packages/types/src/agent/connector-lease.dto.ts` and its unit specification.
|
||||
- Coordinator, TTL caps, grant provenance, reread, and fencing checks: `packages/agent/src/connector-lease.ts` and its unit tests.
|
||||
- Gateway policy, tenant derivation, and default deny wiring: `apps/gateway/src/agent/connector-lease.service.ts` and `agent.module.ts`.
|
||||
- Durable repository and compare-and-swap mutations: `apps/gateway/src/agent/connector-lease.repository.ts`.
|
||||
- Schema and additive migration artifacts: `packages/db/src/schema.ts` and `packages/db/drizzle/0016_salty_morlocks.sql`.
|
||||
- Gateway integration and repository specifications: `apps/gateway/src/agent/connector-lease.integration.test.ts` and `connector-lease.repository.test.ts`.
|
||||
|
||||
These references establish the implemented boundary; they do not imply that a production database, connector policy, or concrete connector is currently active.
|
||||
|
||||
## Explicit non-goals
|
||||
|
||||
M1 does **not** provide or authorize:
|
||||
|
||||
1. Production connector activation, channel cutover, or cross-harness failover/rollback E2E.
|
||||
2. Concrete Claude, Pi, Codex, Matrix, tmux, provider, or channel adapters, or integration of existing runtime providers with this lease context.
|
||||
3. A connector-lease HTTP API or caller-controlled tenant authority.
|
||||
4. Exactly-once connector receipts, a side-effect journal, checkpoint/handoff payloads, replay deduplication, or recovery semantics for an external effect that may already have happened.
|
||||
5. Database-enforced append-only audit rows or database-enforced copies of application identifier/scope/epoch normalization.
|
||||
6. A claim that gateway validation alone fences an effect after an adapter has crossed the boundary; downstream adapters and effect journals remain later work.
|
||||
|
||||
A valid lease or grant is therefore not a claim of exactly-once delivery, production connector readiness, or completed runtime cutover.
|
||||
|
||||
## Related contract
|
||||
|
||||
- [M1 connector lease operations — held/non-operative](../../../ADMIN-GUIDE/operations/mos-connector-lease-operations.md)
|
||||
- [MOS-PORT requirements](../../../PRD.md#mos-runtime-portability-workstream-mos-port)
|
||||
@@ -1,15 +0,0 @@
|
||||
# Architecture RFCs
|
||||
|
||||
> **Status:** Current proposal index. RFCs are draft design material and have no operational or implementation authority until an approved decision and implementation evidence supersede them.
|
||||
|
||||
## Draft proposals
|
||||
|
||||
- [Optional AI egress gateways](optional-ai-egress-gateways.md) — proposed model-egress boundary; LiteLLM and Bifrost are not integrated, and Claudex remains experimental harness tooling.
|
||||
|
||||
A draft RFC must not be cited as a supported feature, deployment path, or approved architecture decision. Approved implemented boundaries belong under [`../decisions/`](../decisions/README.md).
|
||||
|
||||
## Related
|
||||
|
||||
- [[DEVELOPER-GUIDE/architecture/README|Architecture index]]
|
||||
- [[DEVELOPER-GUIDE/architecture/decisions/README|Architecture decisions]]
|
||||
- [[PRD|Product requirements]]
|
||||
@@ -1,371 +0,0 @@
|
||||
# RFC: Optional AI Egress Gateways
|
||||
|
||||
> **Status:** Draft / proposed — not approved, not current, and not integrated.
|
||||
>
|
||||
> **Authority:** Non-operative design proposal. This document does not authorize an
|
||||
> integration, deployment, provider selection, credential flow, or production use.
|
||||
> It is intentionally an RFC rather than an approved architecture decision.
|
||||
>
|
||||
> **Scope:** Optional model/inference egress only. `IProviderAdapter` and
|
||||
> `AgentRuntimeProvider` are separate boundaries; this RFC does not merge them.
|
||||
|
||||
- **Date:** 2026-07-14
|
||||
- **Related issues:** #754, #755
|
||||
- **Decision owner:** Mosaic Gateway / provider-adapter architecture
|
||||
|
||||
## Context
|
||||
|
||||
The emergency Mos continuity path kept Claude Code as the harness and translated
|
||||
Anthropic Messages traffic to Codex OAuth through a small localhost proxy. That
|
||||
preserved the existing Claude Discord plugin and transcript, but exposed two
|
||||
architectural facts:
|
||||
|
||||
1. Harness identity, channel entitlement, provider credentials, inference
|
||||
transport, and runtime sessions are separate concerns.
|
||||
2. A generic AI gateway could eventually improve model routing, budgets, and
|
||||
observability, but it must not become Mosaic's identity, authorization,
|
||||
tenant, connector, or orchestration boundary.
|
||||
|
||||
The Tess qualification work also found that provider rebinding is not, by
|
||||
itself, identity-continuous failover. Any future design still needs a logical
|
||||
agent identity, durable connector lease/fencing, canonical handoff/checkpoint,
|
||||
exactly-once receipts, concrete runtime adapters, and cross-runtime rollback
|
||||
validation.
|
||||
|
||||
This page is a reclassified migration of the historical egress-gateway
|
||||
proposal. The move to `docs/DEVELOPER-GUIDE/architecture/rfcs/` does not promote
|
||||
it to a decision and does not change runtime behavior.
|
||||
|
||||
## Current status and non-goals
|
||||
|
||||
This RFC describes a possible future integration boundary. It does **not** say
|
||||
that any of the candidates below is supported by Mosaic Gateway today:
|
||||
|
||||
- **LiteLLM is not integrated.** It is only a candidate for a future model-egress
|
||||
adapter and remains subject to the prerequisites in this RFC.
|
||||
- **Bifrost is not integrated.** Its routing, virtual-key, and failover features
|
||||
are research inputs only, not Mosaic authority.
|
||||
- **Claudex and `claude-code-proxy` are experimental harness tooling, not
|
||||
gateway egress.** The `mosaic claudex` path runs a Claude Code harness against
|
||||
a local translation proxy for evaluation. It is not a Mosaic Gateway egress
|
||||
integration, does not define the `IProviderAdapter` model contract, and does
|
||||
not define the `AgentRuntimeProvider` runtime/session contract.
|
||||
|
||||
In particular, this RFC does not propose that a generic gateway receive channel
|
||||
traffic directly, own Mosaic sessions, replace the runtime-provider registry,
|
||||
or become a second authorization or tenant system. No database, service, or
|
||||
runtime change is implied by this document.
|
||||
|
||||
## Corrected contract boundary
|
||||
|
||||
The historical proposal conflated two different adapter families. They must
|
||||
remain separate.
|
||||
|
||||
### `IProviderAdapter`: model and inference egress
|
||||
|
||||
`IProviderAdapter` is the model-provider abstraction. Its current contract
|
||||
covers provider registration, model discovery, provider health, and a future
|
||||
direct completion stream. `ProviderService` aggregates these adapters and
|
||||
connects model availability to the Pi `ModelRegistry`.
|
||||
|
||||
It does **not** represent an agent process or session. It does not own channel
|
||||
identity, Mosaic actor or tenant identity, logical-agent ownership, runtime
|
||||
session IDs, runtime attachments, handoff state, or tool authorization. An
|
||||
optional LiteLLM, Bifrost, or similar model gateway would therefore be a
|
||||
candidate for this model-egress path only, after approval and qualification.
|
||||
|
||||
### `AgentRuntimeProvider`: runtime and session boundary
|
||||
|
||||
`AgentRuntimeProvider` is the runtime-neutral session contract. It covers
|
||||
runtime capabilities and health plus operations such as listing sessions,
|
||||
reading session trees, streaming a session, sending a message, attaching or
|
||||
detaching, and terminating a session. Its `RuntimeScope` is derived from
|
||||
trusted actor, tenant, channel, and correlation context.
|
||||
|
||||
The runtime-provider service performs the gateway-side capability, authorization,
|
||||
approval, and metadata-only audit boundary before invoking a runtime provider.
|
||||
It is not a model-egress gateway and must not be substituted for
|
||||
`IProviderAdapter`. A runtime implementation may use model selection or a model
|
||||
service internally, but that dependency is an explicit composition between two
|
||||
contracts; it does not make the runtime provider a model provider or make a
|
||||
model gateway a session provider.
|
||||
|
||||
The checked-in contract and implementation references are:
|
||||
|
||||
- [`IProviderAdapter` and provider types](../../../../packages/types/src/provider/index.ts)
|
||||
- [`ProviderService`](../../../../apps/gateway/src/agent/provider.service.ts)
|
||||
- [`AgentRuntimeProvider`](../../../../packages/types/src/agent/agent-runtime-provider.ts)
|
||||
- [`RuntimeProviderService`](../../../../apps/gateway/src/agent/runtime-provider-registry.service.ts)
|
||||
- [`AgentRuntimeProviderRegistry`](../../../../packages/agent/src/runtime-provider-registry.ts)
|
||||
|
||||
### Proposed relationship
|
||||
|
||||
If a future implementation is approved, the model and runtime paths remain
|
||||
parallel and explicitly composed at the Mosaic boundary:
|
||||
|
||||
```text
|
||||
Discord / Matrix / CLI / web
|
||||
|
|
||||
v
|
||||
Mosaic Gateway: authenticated actor + tenant, policy, approvals,
|
||||
logical agent, connector lease/fence, audit, checkpoints,
|
||||
idempotency, and side-effect receipts
|
||||
|
|
||||
+-----+-----------------------+
|
||||
| |
|
||||
v v
|
||||
model request path runtime/session path
|
||||
ProviderService / routing RuntimeProviderService
|
||||
| |
|
||||
v v
|
||||
IProviderAdapter AgentRuntimeProvider
|
||||
| |
|
||||
v v
|
||||
optional model-egress native or external runtime/session
|
||||
gateway (future only) transport
|
||||
|
|
||||
v
|
||||
upstream model/provider
|
||||
```
|
||||
|
||||
The optional egress gateway may receive only a validated model request from the
|
||||
Mosaic model path. It is not a channel ingress, runtime-session transport,
|
||||
connector owner, or source of Mosaic identity.
|
||||
|
||||
## Draft proposal
|
||||
|
||||
This RFC proposes, for review only, that Mosaic could support an optional
|
||||
model-egress gateway through a dedicated `IProviderAdapter` implementation or
|
||||
adapter-owned model transport. Any such integration would remain subordinate
|
||||
to Mosaic Gateway policy and would not add a second runtime/session boundary.
|
||||
|
||||
Mosaic Gateway would remain authoritative for:
|
||||
|
||||
- authenticated actor and tenant identity;
|
||||
- logical-agent identity, connector binding, lease epoch, and stale-holder
|
||||
fencing;
|
||||
- authorization, approval, and model/tool policy;
|
||||
- runtime/session access through the separate `AgentRuntimeProvider` boundary;
|
||||
- audit correlation, redaction, retention, and operational evidence;
|
||||
- canonical handoff, checkpoint, and recovery state; and
|
||||
- idempotency keys, operation identity, and durable side-effect receipts.
|
||||
|
||||
An optional model-egress gateway must not:
|
||||
|
||||
- receive channel ingress directly;
|
||||
- authorize tools, connector ownership, runtime sessions, or approvals;
|
||||
- define Mosaic actors, tenants, logical agents, or session identity;
|
||||
- treat downstream virtual keys as Mosaic principals;
|
||||
- persist raw Mosaic handoffs, channel credentials, or unredacted telemetry;
|
||||
- bypass adapter capability negotiation or gateway policy;
|
||||
- retry or fail over an operation whose side-effect state is ambiguous; or
|
||||
- silently select an unhealthy or unauthorized provider merely to return a
|
||||
result.
|
||||
|
||||
## Candidate assessment
|
||||
|
||||
These dispositions are deliberately non-integrated and do not constitute
|
||||
approval.
|
||||
|
||||
### LiteLLM
|
||||
|
||||
**Disposition:** Not integrated; future candidate for a formal
|
||||
`IProviderAdapter` model-egress prototype only.
|
||||
|
||||
Potentially useful features include broad provider routing, virtual keys,
|
||||
budgets, observability, and OpenAI/Anthropic-compatible surfaces. A future
|
||||
review must verify, rather than assume, the exact ChatGPT subscription OAuth
|
||||
flow, supported models, provider terms, token storage, encryption, revocation,
|
||||
refresh, scope, and incident response.
|
||||
|
||||
A prototype would also have to prove streaming, tool calls, reasoning controls,
|
||||
cancellation, tenant isolation, audit-correlation preservation, retry behavior,
|
||||
and idempotency. Virtual keys must remain downstream credentials and must not
|
||||
become Mosaic actors or tenants. Channel ingress and connector credentials
|
||||
would remain outside LiteLLM.
|
||||
|
||||
Source references:
|
||||
|
||||
- [LiteLLM ChatGPT subscription provider](https://docs.litellm.ai/docs/providers/chatgpt)
|
||||
- [LiteLLM providers](https://docs.litellm.ai/docs/providers)
|
||||
|
||||
### Bifrost
|
||||
|
||||
**Disposition:** Not integrated; future candidate for governance and routing
|
||||
research, with subscription OAuth compatibility unverified.
|
||||
|
||||
Virtual keys, budgets, rate limits, weighted load balancing, and provider
|
||||
failover may inform a future Mosaic egress design, but they are not Mosaic
|
||||
authority. A future review must verify Codex/ChatGPT subscription OAuth rather
|
||||
than assume API-key compatibility, map all policy to server-derived Mosaic
|
||||
tenants, prove that failover preserves connector leases and approvals, and
|
||||
redact request/response telemetry before persistence.
|
||||
|
||||
Automatic failover must be disabled or constrained whenever policy, approval,
|
||||
or side-effect state is ambiguous.
|
||||
|
||||
Source references:
|
||||
|
||||
- [Bifrost overview](https://docs.getbifrost.ai/overview)
|
||||
- [Bifrost repository](https://github.com/maximhq/bifrost)
|
||||
|
||||
### Claudex / `claude-code-proxy`
|
||||
|
||||
**Disposition:** Experimental harness overlay and local translation proxy; not
|
||||
Mosaic Gateway egress and not an approved provider integration.
|
||||
|
||||
The reviewed path runs GPT models inside the Claude Code harness through a
|
||||
local `claude-code-proxy` that translates Anthropic Messages traffic to a
|
||||
ChatGPT-subscription (Codex OAuth) backend. It is intended for evaluation and
|
||||
must not be described as a current Mosaic model gateway, an `IProviderAdapter`
|
||||
implementation, or an `AgentRuntimeProvider` implementation.
|
||||
|
||||
Its constraints remain important: it is not a multi-tenant control plane, it
|
||||
must not own connector leasing or canonical handoff, and local proxy
|
||||
credentials and listener exposure require isolation. The current Mosaic
|
||||
launcher documents its experimental status and isolated Claude configuration:
|
||||
|
||||
- [`mosaic` claudex documentation](../../../../packages/mosaic/README.md)
|
||||
- [`claudex` launch composition](../../../../packages/mosaic/src/commands/claudex.ts)
|
||||
- [`claude-code-proxy`](https://github.com/raine/claude-code-proxy)
|
||||
|
||||
### `teremterem/claude-code-gpt-5-codex`
|
||||
|
||||
**Disposition:** Historical recipe; not selected and not integrated.
|
||||
|
||||
The reviewed repository uses `OPENAI_API_KEY`, tells previously authenticated
|
||||
Claude users to log out, and documents a Claude Web Search schema
|
||||
incompatibility. That does not satisfy the subscription-OAuth plus built-in-
|
||||
channel continuity requirement observed in the Mos cutover.
|
||||
|
||||
Source references:
|
||||
|
||||
- [Repository](https://github.com/teremterem/claude-code-gpt-5-codex)
|
||||
- [Environment template](https://github.com/teremterem/claude-code-gpt-5-codex/blob/main/.env.template)
|
||||
|
||||
## Prerequisites before approval or integration
|
||||
|
||||
No candidate may be integrated, enabled as a Mosaic feature, or treated as a
|
||||
current supported path until all of the following are complete for the exact
|
||||
provider, adapter, configuration, and deployed revision.
|
||||
|
||||
### 1. Recorded approval and governance
|
||||
|
||||
- An architecture decision explicitly approves the model-egress scope and
|
||||
records that `IProviderAdapter` remains separate from `AgentRuntimeProvider`.
|
||||
- Product/operations ownership, provider terms review, and independent security
|
||||
review are recorded against the exact change and provider revision.
|
||||
- The approval identifies allowed providers, models, regions, data handling,
|
||||
rollback owner, support status, and a time-bounded experimental or production
|
||||
phase. This RFC itself is not that approval.
|
||||
- No candidate is advertised as integrated, current, or production-ready while
|
||||
the approval record is absent or expired.
|
||||
|
||||
### 2. Security and credential controls
|
||||
|
||||
- A threat model covers prompt/tool data, model output, streaming, cancellation,
|
||||
retries, failover, SSRF, endpoint authentication, TLS, egress allowlists,
|
||||
supply-chain risk, provider terms, and denial-of-service behavior.
|
||||
- OAuth tokens, API keys, virtual keys, refresh tokens, and proxy credentials
|
||||
have documented ownership, storage, encryption, rotation, revocation,
|
||||
expiry, least-privilege scope, and incident-response procedures. Secrets do
|
||||
not enter prompts, logs, traces, audit payloads, or commits.
|
||||
- Request, response, tool-schema, and error telemetry is classified and
|
||||
redacted before persistence or external channel delivery. Retention and
|
||||
deletion are tenant-scoped.
|
||||
- The adapter fails closed on missing, expired, revoked, malformed, or
|
||||
unauthorized credentials and on uncertain provider health. Loopback-only
|
||||
experimental proxies remain process-isolated and cannot become a gateway
|
||||
bypass.
|
||||
|
||||
### 3. Actor and tenant isolation
|
||||
|
||||
- Actor and tenant identity are derived from authenticated Mosaic context at
|
||||
the Gateway; callers cannot select a tenant, logical agent, credential, or
|
||||
provider principal by supplying an ID.
|
||||
- Downstream virtual keys and provider account identifiers are mapped to
|
||||
server-owned tenant policy. They never grant Mosaic authorization and never
|
||||
replace RBAC, approvals, connector leases, or runtime scope.
|
||||
- Model configuration, budgets, rate limits, data residency, credential use,
|
||||
logs, caches, and failure handling are isolated per tenant. Cross-tenant
|
||||
reads, writes, cache hits, telemetry, and failover are denied and tested.
|
||||
- The egress adapter receives only the minimum scoped request needed for the
|
||||
authorized model operation; channel ingress and runtime/session control stay
|
||||
in Mosaic-owned boundaries.
|
||||
|
||||
### 4. Idempotency and side-effect safety
|
||||
|
||||
- Mosaic assigns a durable operation ID and idempotency key before an egress
|
||||
request can cause a tool or external side effect. The provider gateway must
|
||||
preserve the correlation and idempotency metadata or be wrapped by an
|
||||
adapter that does so.
|
||||
- Durable receipts record request, attempt, provider, outcome, and replay state
|
||||
without storing unredacted content. Retries and failover are allowed only
|
||||
when the operation contract proves they cannot duplicate a side effect.
|
||||
- Ambiguous timeout, disconnect, stream-resume, cancellation, and provider
|
||||
failover outcomes fail closed until the receipt is reconciled. The egress
|
||||
gateway must not claim exactly-once behavior that Mosaic has not proven.
|
||||
- Failure injection demonstrates no duplicate tool, connector, channel, or
|
||||
external side effect across gateway, adapter, proxy, and provider retries.
|
||||
|
||||
### 5. Contract and rollback qualification
|
||||
|
||||
- Separate contract tests pass for `IProviderAdapter` model registration,
|
||||
health, streaming, tools, reasoning controls, cancellation, errors, and
|
||||
audit correlation.
|
||||
- Separate `AgentRuntimeProvider` contract tests continue to pass for runtime
|
||||
capability negotiation, session ownership, approval, attach/detach,
|
||||
termination, and normalized events. A model-egress candidate must not be
|
||||
used as evidence for runtime/session compatibility.
|
||||
- A verified rollback to the prior model path is exercised, including revoked
|
||||
credentials, unhealthy providers, partial streams, and an adapter version
|
||||
mismatch.
|
||||
- The exact deployed revision receives independent code and security review,
|
||||
with terminal-green CI and operator recovery evidence before any activation.
|
||||
|
||||
## Security consequences
|
||||
|
||||
- Subscription OAuth grants are high-value credentials and require the same
|
||||
lifecycle controls as service credentials.
|
||||
- Downstream virtual keys reduce provider-key exposure but do not establish
|
||||
user, tenant, agent, or runtime authority.
|
||||
- Automatic retry or failover can duplicate tool and external side effects
|
||||
unless Mosaic owns operation IDs, durable receipts, and reconciliation.
|
||||
- Gateway telemetry can contain prompts, tool schemas, and model output;
|
||||
redaction and retention policy must apply before persistence.
|
||||
- A localhost translation endpoint must remain loopback-only, process-isolated,
|
||||
authenticated where applicable, and outside the Mosaic Gateway ingress path.
|
||||
- A model-egress gateway outage must not weaken Mosaic authorization, lease
|
||||
fencing, tenant isolation, approval, or runtime-session boundaries.
|
||||
|
||||
## Acceptance before any production use
|
||||
|
||||
The following are minimum exit criteria for a future, separately approved
|
||||
implementation; they are not satisfied by this RFC:
|
||||
|
||||
1. The recorded approval and provider-terms review cover the exact integration.
|
||||
2. Credential lifecycle, revocation, rotation, redaction, and incident drills
|
||||
are documented and exercised.
|
||||
3. Tenant-bound authorization remains entirely in Mosaic Gateway and passes
|
||||
cross-tenant negative tests.
|
||||
4. `IProviderAdapter` contract tests pass without treating
|
||||
`AgentRuntimeProvider` tests as substitutes.
|
||||
5. Failure injection proves no duplicate side effects across retries or
|
||||
provider failover, with durable idempotency receipts.
|
||||
6. Streaming, tools, cancellation, reasoning policy, errors, and audit
|
||||
correlation are qualified for the exact model path.
|
||||
7. Rollback to the prior provider path is exercised and operator-verifiable.
|
||||
8. Independent code and security reviews approve the exact deployed revision.
|
||||
|
||||
## Follow-up
|
||||
|
||||
- #754 owns cross-runtime logical identity, checkpoint, receipt, adapter, and
|
||||
failover work.
|
||||
- #755 / PR #757 implements the first logical identity and connector
|
||||
lease/fencing boundary.
|
||||
- A later issue may prototype LiteLLM or Bifrost behind the model-provider
|
||||
boundary only after the recorded approval, security, tenant, idempotency,
|
||||
contract, and rollback prerequisites are met.
|
||||
- The page remains **Draft / proposed** until an explicit decision changes its
|
||||
status. Until then, it must not be cited as an approved architecture,
|
||||
current integration, or operational runbook.
|
||||
@@ -1,181 +0,0 @@
|
||||
# Channel adapters
|
||||
|
||||
> **Status:** Current shared channel types plus the Discord reference/compatibility implementation. A shared gateway adapter registry, Telegram parity, and Matrix channel integration remain unimplemented or unproven.
|
||||
>
|
||||
> **Last verified:** 2026-08-10 against the source and focused tests listed in [Evidence](#evidence).
|
||||
>
|
||||
> **Audience:** Developers implementing or reviewing channel integrations.
|
||||
|
||||
The gateway remains the policy and runtime boundary. Channel code translates native events, applies its native admission checks, and delivers normalized ingress/egress; it must not choose a provider, harness, process, or native runtime session on behalf of the gateway.
|
||||
|
||||
## Current source boundaries
|
||||
|
||||
| Boundary | Current authority | Current claim |
|
||||
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Shared contract | [`packages/types/src/channel/channel.dto.ts`](../../../packages/types/src/channel/channel.dto.ts), [`channel-adapter.ts`](../../../packages/types/src/channel/channel-adapter.ts) | DTOs, ports, lifecycle health, and delivery error codes exported by `@mosaicstack/types`. |
|
||||
| Discord translation | [`plugins/discord/src/index.ts`](../../../plugins/discord/src/index.ts) | First adapter implementing the shared lifecycle/egress seam, with an optional direct ingress port and a tested Socket.IO compatibility path. |
|
||||
| Discord behavior | [`plugins/discord/src/index.test.ts`](../../../plugins/discord/src/index.test.ts) | Current allowlist, pairing, role, thread, route, attachment, replay-envelope, egress, retry, and health behavior. |
|
||||
| Gateway compatibility | [`apps/gateway/src/chat/chat.gateway.ts`](../../../apps/gateway/src/chat/chat.gateway.ts), [`chat.gateway-auth.ts`](../../../apps/gateway/src/chat/chat.gateway-auth.ts) | `/chat` Socket.IO service/session authentication, signed Discord envelope validation, trusted binding selection, raw chat dispatch, and raw stream egress. |
|
||||
| Host registry | [`apps/gateway/src/plugin/plugin.interface.ts`](../../../apps/gateway/src/plugin/plugin.interface.ts), [`plugin.module.ts`](../../../apps/gateway/src/plugin/plugin.module.ts), [`plugin.service.ts`](../../../apps/gateway/src/plugin/plugin.service.ts) | Lifecycle-only `IChannelPlugin[]` hosting. This is not a universal `OfficialChannelAdapter` registry. |
|
||||
| Telegram | [`plugins/telegram/src/index.ts`](../../../plugins/telegram/src/index.ts), [`package.json`](../../../plugins/telegram/package.json) | Raw legacy Telegraf/Socket.IO behavior only; no shared-contract or authenticated gateway parity. |
|
||||
| Matrix | No current channel adapter boundary in the cited implementation | Matrix-related fleet/runtime code is not evidence of a gateway channel adapter. |
|
||||
|
||||
Executable source and tests outrank older architecture or quarantine pages. The canonical architecture summary is [`architecture/channel-protocol.md`](../architecture/channel-protocol.md).
|
||||
|
||||
## Shared contract
|
||||
|
||||
`@mosaicstack/types` currently exports the channel types through [`packages/types/src/channel/index.ts`](../../../packages/types/src/channel/index.ts) and [`packages/types/src/index.ts`](../../../packages/types/src/index.ts).
|
||||
|
||||
The lifecycle and port seams are:
|
||||
|
||||
```typescript
|
||||
interface OfficialChannelAdapter {
|
||||
readonly name: string;
|
||||
start(): Promise<void>;
|
||||
stop(): Promise<void>;
|
||||
health(): Promise<ChannelAdapterHealthDto>;
|
||||
}
|
||||
|
||||
interface ChannelIngressPort {
|
||||
receive(ingress: ChannelIngressDto): Promise<void>;
|
||||
}
|
||||
|
||||
interface ChannelEgressPort {
|
||||
send(egress: ChannelEgressDto): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
The current DTO boundary includes:
|
||||
|
||||
- `ChannelMessageDto` for normalized native messages and JSON-safe metadata;
|
||||
- `ChannelAttachmentDto` for bounded external attachment references;
|
||||
- `ChannelAuthorizedPrincipalDto` for the already-authorized channel actor and `viewer`/`operator`/`admin` role;
|
||||
- `ChannelBindingDto` for configuration-owned workspace/channel/logical-agent binding;
|
||||
- `ChannelResponseTargetDto` for a channel and optional thread;
|
||||
- `ChannelConversationRouteDto` for binding, logical agent, stable conversation ID, authorization channel, and response target;
|
||||
- `ChannelIngressDto` for correlation, native message ID, operation, principal, message, and route; and
|
||||
- `ChannelEgressDto` for correlation, normalized output, and route.
|
||||
|
||||
Current operations are `message.send`, `approval.create`, and `session.stop`. Current delivery errors are `invalid_route`, `destination_unavailable`, and `delivery_failed`; there is no shared revoked-auth error code or executable protocol-version contract in this surface.
|
||||
|
||||
### Stable route rule
|
||||
|
||||
The Discord adapter derives:
|
||||
|
||||
```text
|
||||
<logical-agent-id>:discord:<response-channel-id>
|
||||
```
|
||||
|
||||
The binding address is derived from the configured guild, parent channel, and logical-agent instance. The route intentionally omits runtime provider, harness, model, process, and native runtime-session identifiers. Gateway provider/runtime layers own those identities; durable-session ownership applies only after explicit enrollment and is not implied by the external route.
|
||||
|
||||
This is a route-integrity rule, not proof that the gateway has a universal channel session API. A future adapter must derive its route from trusted configuration and native channel/thread identity; it must not accept a caller-selected logical agent or runtime target.
|
||||
|
||||
## Current Discord implementation
|
||||
|
||||
### Native ingress
|
||||
|
||||
`DiscordPlugin` currently:
|
||||
|
||||
1. ignores bot-authored and non-guild messages;
|
||||
2. resolves a thread's actual parent text channel, while leaving normal category parents out of authorization;
|
||||
3. applies default-deny guild, parent-channel, and user allowlists;
|
||||
4. resolves configuration-owned `instanceId`/`agentConfigId` bindings and paired-user roles before thread creation or dispatch;
|
||||
5. applies message and mention-thread limits before side effects;
|
||||
6. creates/reuses a mention thread or preserves an existing thread target; and
|
||||
7. maps the event to a `ChannelIngressDto` when an `ingressPort` dependency is supplied.
|
||||
|
||||
The normalized message uses `channelName: "discord"`, the response target as `channelId`, `senderKind: "user"`, `markdown` for non-empty text, `image`/`file` for attachment-only input, mapped attachments, and metadata containing the native channel message ID and guild ID. It does not currently claim a universal metadata shape for mentions, embeds, channel type, or replies.
|
||||
|
||||
### Socket.IO compatibility path
|
||||
|
||||
The gateway-hosted plugin is currently constructed without a direct `ChannelIngressPort` in [`plugin.module.ts`](../../../apps/gateway/src/plugin/plugin.module.ts), so it uses the established compatibility path:
|
||||
|
||||
1. `start()` connects to `${DISCORD_GATEWAY_URL}/chat` with `auth.discordServiceToken`.
|
||||
2. Normal sends emit a signed `message` envelope; approval and stop emit `discord:approve` and `discord:stop` envelopes.
|
||||
3. The HMAC-SHA-256 signature covers the ordered Discord payload using `DISCORD_SERVICE_TOKEN`.
|
||||
4. The gateway verifies the service token/signature, allowlists, binding/operation role, stable conversation ID, attachment bounds, and replay key before dispatch.
|
||||
5. The gateway selects the binding's trusted `agentConfigId` and verifies its name equals the logical-agent instance. It attempts normal conversation binding/persistence before dispatch, but the external route is not a UUID and no route-to-UUID mapping currently proves durable ordinary-chat history.
|
||||
6. Agent output currently returns as raw Socket.IO `agent:start`, `agent:text`, and `agent:end` events. The plugin buffers the text and calls its typed Discord egress at stream end.
|
||||
|
||||
This compatibility path carries enough normalized identity to preserve current security and routing behavior, but it is not a gateway-produced `ChannelIngressDto`/`ChannelEgressDto` flow through a shared host registry. The gateway can continue live dispatch after persistence failure; adapter authors must not claim durable continuity until external routes map to UUID conversations and fresh-message restart tests pass.
|
||||
|
||||
### Egress and health
|
||||
|
||||
`DiscordPlugin.send()` is a typed `ChannelEgressPort` implementation. It validates the route and message alignment before destination lookup, sends at a 1,900-character boundary, retries transient 429/5xx/network failures up to three times, uses one deterministic enforced nonce per correlation/chunk, and does not retry permanent failures. It reports `connected`, `degraded`, or `disconnected` from Discord client readiness and gateway socket connectivity.
|
||||
|
||||
The host wrapper currently exposes only `name`, `start`, `stop`, and optional project provisioning. It does not expose `health()`, inject the direct ingress port, produce `ChannelEgressDto` values from the gateway, or provide `healthAll`/`getAdapter` semantics.
|
||||
|
||||
## Adapter authoring boundary
|
||||
|
||||
For a future official adapter, preserve these current architectural boundaries:
|
||||
|
||||
1. Normalize native messages to the shared DTOs and preserve native message ID, correlation ID, channel/thread identity, attachments, and response target.
|
||||
2. Enforce native guild/room/channel/user/pairing/role policy before thread/room creation or gateway dispatch.
|
||||
3. Select the logical agent from trusted configuration; never from a caller-controlled provider, model, harness, or route field.
|
||||
4. Keep the route stable when the gateway changes runtime provider or harness.
|
||||
5. Validate egress route and destination before sending; bound chunks, retries, and attachment metadata.
|
||||
6. Return sanitized errors and expose non-throwing lifecycle health for ordinary disconnected state.
|
||||
7. Add happy-path and failure-path tests for authorization ordering, replay/idempotency, route integrity, native side effects, egress, reconnect, and health.
|
||||
|
||||
These are implementation constraints for future work, not evidence that the missing shared registry already exists.
|
||||
|
||||
## Parity status
|
||||
|
||||
### Telegram: raw legacy adapter, not shared parity
|
||||
|
||||
The current Telegram source:
|
||||
|
||||
- launches Telegraf and a Socket.IO client;
|
||||
- reads `TELEGRAM_BOT_TOKEN` and `TELEGRAM_GATEWAY_URL` through the gateway plugin factory, whose URL default is `http://localhost:14242`;
|
||||
- accepts text messages only and ignores attachment-only messages;
|
||||
- maps each Telegram `chat.id` to `telegram-<chatId>`;
|
||||
- emits a raw `{ conversationId, content, role: "user" }` object rather than `ChannelIngressDto`;
|
||||
- has no shared DTO import, channel binding, principal/role policy, native message ID, attachment mapping, route-safe egress, or health method; and
|
||||
- has no package test file in this checkout; its script is `vitest run --passWithNoTests`.
|
||||
|
||||
Its Socket.IO connection does not send the Discord service token or a BetterAuth session. A configured `TELEGRAM_BOT_TOKEN` therefore must not be described as an authenticated official channel. Shared Telegram parity requires a separate implementation and focused security/contract tests.
|
||||
|
||||
### Matrix: no current channel adapter
|
||||
|
||||
No current gateway adapter, shared-port wiring, channel binding, identity resolver, persistence boundary, authentication path, or focused channel test establishes Matrix as a Mosaic channel. Matrix code elsewhere in the repository belongs to other transport/runtime work and must not be promoted into channel-adapter instructions without a separate contract and evidence.
|
||||
|
||||
### Shared registry: draft/unimplemented
|
||||
|
||||
The current `PLUGIN_REGISTRY` is an array of `IChannelPlugin` lifecycle wrappers. It is not a registry of `OfficialChannelAdapter` instances and does not inject `ChannelIngressPort`/`ChannelEgressPort`, aggregate adapter health, or remove the gateway's Discord-specific auth/envelope/approval/stop/replay branches.
|
||||
|
||||
A future registry must specify binding and credential ownership, ingress/egress injection, health/error semantics, compatibility with the existing Socket.IO clients, and tests proving that adapters cannot bypass gateway authorization or route validation before it can be documented as current architecture.
|
||||
|
||||
## Safe verification commands
|
||||
|
||||
The focused package commands used by the current Discord evidence are:
|
||||
|
||||
```bash
|
||||
pnpm --filter @mosaicstack/types build
|
||||
pnpm --filter @mosaicstack/types typecheck
|
||||
pnpm --filter @mosaicstack/discord-plugin typecheck
|
||||
pnpm --filter @mosaicstack/discord-plugin lint
|
||||
pnpm --filter @mosaicstack/discord-plugin test
|
||||
cd apps/gateway && pnpm exec vitest run \
|
||||
src/plugin/discord-ingress.security.spec.ts \
|
||||
src/chat/chat.gateway-redaction.spec.ts \
|
||||
src/__tests__/integration/tess-cross-surface.integration.test.ts
|
||||
```
|
||||
|
||||
These commands do not require starting Gateway, Discord, Telegram, Matrix, a queue, or a database. The Discord package test includes its configured coverage thresholds; the gateway command is a focused Vitest run rather than a claim of full repository integration coverage.
|
||||
|
||||
## Evidence
|
||||
|
||||
- [`packages/types/src/channel/channel.dto.ts`](../../../packages/types/src/channel/channel.dto.ts) — shared DTOs, operations, route fields, and metadata types.
|
||||
- [`packages/types/src/channel/channel-adapter.ts`](../../../packages/types/src/channel/channel-adapter.ts) — adapter lifecycle, ingress/egress ports, and delivery errors.
|
||||
- [`plugins/discord/src/index.ts`](../../../plugins/discord/src/index.ts) — native translation, auth ordering, compatibility envelope, route-safe egress, retry, and health.
|
||||
- [`plugins/discord/src/index.test.ts`](../../../plugins/discord/src/index.test.ts) — focused Discord contract and behavior tests.
|
||||
- [`apps/gateway/src/chat/chat.gateway.ts`](../../../apps/gateway/src/chat/chat.gateway.ts) — service/session auth, signed envelope validation, replay, trusted agent selection, and raw stream events.
|
||||
- [`apps/gateway/src/chat/chat.gateway-auth.ts`](../../../apps/gateway/src/chat/chat.gateway-auth.ts) — timing-safe Discord service-token and BetterAuth session checks.
|
||||
- [`apps/gateway/src/plugin/discord-ingress.security.spec.ts`](../../../apps/gateway/src/plugin/discord-ingress.security.spec.ts) — gateway security and privileged-operation tests.
|
||||
- [`apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts`](../../../apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts) — control-flow test with explicit durable-session pre-enrollment; not ordinary Discord persistence evidence.
|
||||
- [`apps/gateway/src/plugin/plugin.interface.ts`](../../../apps/gateway/src/plugin/plugin.interface.ts), [`plugin.module.ts`](../../../apps/gateway/src/plugin/plugin.module.ts), and [`plugin.service.ts`](../../../apps/gateway/src/plugin/plugin.service.ts) — lifecycle-only host registry.
|
||||
- [`plugins/telegram/src/index.ts`](../../../plugins/telegram/src/index.ts) and [`plugins/telegram/package.json`](../../../plugins/telegram/package.json) — raw Telegram behavior and no-test script.
|
||||
- [Canonical channel protocol architecture](../architecture/channel-protocol.md) — shared contract and explicit current/draft boundary.
|
||||
- [Discord ingress security](../../ADMIN-GUIDE/security/discord-ingress.md) — administrator-facing config and auth claims.
|
||||
- [Discord conversations](../../USER-GUIDE/workflows/discord-conversations.md) — user-facing routing behavior.
|
||||
- [Developer Guide](../README.md)
|
||||
@@ -1,292 +0,0 @@
|
||||
---
|
||||
title: Lease-broker operations
|
||||
type: runbook
|
||||
audience: developer
|
||||
status: current
|
||||
source_of_truth: false
|
||||
---
|
||||
|
||||
# Lease-broker operations
|
||||
|
||||
> **Status:** Current for repository inspection and test verification. Live broker
|
||||
> startup, recovery, lease mutation, service management, and cleanup remain
|
||||
> **held/non-operative**.
|
||||
>
|
||||
> **Operational authority:** This page authorizes only the non-mutating
|
||||
> inspection and test commands in [Safe static inspection](#safe-static-inspection).
|
||||
> It does not authorize starting a daemon or systemd unit, connecting to a live
|
||||
> socket, invoking recovery, promoting or revoking a lease, executing a
|
||||
> consequential runtime tool, or changing a database.
|
||||
|
||||
The lease broker is a Linux-only internal process boundary. Its executable
|
||||
behavior is authoritative in the [shipped broker daemon](../../../packages/mosaic/framework/tools/lease-broker/daemon.py)
|
||||
and tests, not in this page. The current architecture references are:
|
||||
|
||||
- [Broker protocol](../architecture/lease-broker-protocol.md) — framing,
|
||||
kernel identity, ancestry, generations, persistence, and state transitions.
|
||||
- [Lease-broker security](../architecture/lease-broker-security.md) — trust
|
||||
boundaries, filesystem hardening, observer behavior, and residuals.
|
||||
- [Whole mutator-class gate](../architecture/mutator-class-gate.md) — default
|
||||
deny, launch choke points, and broker-owned promotion order.
|
||||
- [Compaction revocation](../architecture/compaction-revocation.md) — Claude
|
||||
and Pi lifecycle observers, generation fencing, and the bounded residual.
|
||||
|
||||
## Safe static inspection
|
||||
|
||||
These are the only operative commands documented here. They inspect checked-in
|
||||
files or run isolated tests; they do not start a user service, activate a
|
||||
runtime, connect to PostgreSQL, or mutate repository/product state.
|
||||
|
||||
### Source and launch inventory
|
||||
|
||||
From the repository root, inspect the current implementation and its permanent
|
||||
runtime-launch inventory:
|
||||
|
||||
```bash
|
||||
find packages/mosaic/framework/tools/lease-broker packages/mosaic/src/lease-broker packages/mosaic/src/mutator-gate -maxdepth 1 -type f -print | sort
|
||||
python3 packages/mosaic/framework/tools/lease-broker/check-runtime-launches.py --root . --json
|
||||
```
|
||||
|
||||
The launch inventory is a static completeness guard. A clean result means the
|
||||
checked-in production launch sites are classified by the guard; it does not
|
||||
prove that a broker, runtime, or service is running.
|
||||
|
||||
### Safe unit and static contract tests
|
||||
|
||||
The focused standard-library tests can be run directly:
|
||||
|
||||
```bash
|
||||
python3 packages/mosaic/src/lease-broker/daemon_deadline_unittest.py
|
||||
python3 packages/mosaic/src/lease-broker/normative_fragments_unittest.py
|
||||
python3 packages/mosaic/src/lease-broker/receipt_challenge_unittest.py
|
||||
python3 packages/mosaic/src/lease-broker/context_recovery_unittest.py
|
||||
python3 packages/mosaic/src/lease-broker/state_store_unittest.py
|
||||
python3 packages/mosaic/src/lease-broker/framework_skill_portability_unittest.py
|
||||
python3 packages/mosaic/src/mutator-gate/runtime_tools_unittest.py
|
||||
python3 packages/mosaic/src/mutator-gate/runtime_launch_guard_unittest.py
|
||||
python3 packages/mosaic/src/mutator-gate/version_coupling_unittest.py
|
||||
```
|
||||
|
||||
`recovery_runtime_unittest.py` and `recovery_b1_adversarial_unittest.py` are
|
||||
also safe when run as tests: they use private temporary daemons, sockets, and
|
||||
fixtures, never the installed user service or a model stream. They are not
|
||||
operator recovery instructions:
|
||||
|
||||
```bash
|
||||
python3 packages/mosaic/src/lease-broker/recovery_runtime_unittest.py
|
||||
python3 packages/mosaic/src/lease-broker/recovery_b1_adversarial_unittest.py
|
||||
```
|
||||
|
||||
The [lease-broker Vitest acceptance suite](../../../packages/mosaic/src/lease-broker/lease-broker.acceptance.spec.ts)
|
||||
and [mutator-gate Vitest acceptance suite](../../../packages/mosaic/src/mutator-gate/mutator-gate.acceptance.spec.ts)
|
||||
provide additional private-fixture coverage. Test-created child processes and
|
||||
Unix sockets are disposable test fixtures, not live-service authority.
|
||||
|
||||
## Current implementation facts
|
||||
|
||||
### Protected paths and persistence
|
||||
|
||||
The broker and supervisor source establish these invariants:
|
||||
|
||||
| Object | Current contract |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Parent directory | The parent containing the socket and state must already exist and have exactly mode `0700`. |
|
||||
| Broker socket | The daemon refuses an existing path or symlink, binds a new Unix socket, sets it to `0600`, and removes only the inode it created during normal shutdown. |
|
||||
| State file | A present state file must be a regular, non-symlink file protected as mode `0600`, no larger than 4 MiB, and valid state-version-1 JSON. Corrupt, incompatible, oversized, or unsafe state refuses startup. |
|
||||
| State writes | Changes are serialized through a mode-`0600` temporary file, complete-write loop, `fsync`, atomic replace, and parent-directory `fsync`. Post-replace durability uncertainty poisons the store and terminates service processing. |
|
||||
| Volatile authority | `VERIFIED` leases are not restored as live authority after broker restart. Persisted session identity and valid pending-token state are separate from volatile lease state. |
|
||||
| Runtime generation | `launch-runtime.py` creates `generation-<broker-session>.state` beside the socket. It is an owner-only, locked, monotonic generation file; unsafe, non-regular, oversized, or non-private state fails closed. |
|
||||
|
||||
The resolved socket path is, in order: explicit
|
||||
`MOSAIC_LEASE_BROKER_SOCKET`, `$XDG_RUNTIME_DIR/mosaic-lease/broker.sock`, or
|
||||
`/run/user/<uid>/mosaic-lease/broker.sock`. The state file is `state.json` next
|
||||
to that resolved socket. The production observer transport is a separate
|
||||
`receipt-observer.sock` by default; `--test-observer-file` is a private test
|
||||
fixture option, not a production deployment path.
|
||||
|
||||
The supervisor implementation can materialize a user unit, wrapper, and
|
||||
co-located daemon sources under caller-supplied paths, but
|
||||
[`applyBrokerSupervisor`](../../../packages/mosaic/src/lease-broker/broker-supervisor.ts)
|
||||
never runs `systemctl`, starts `daemon.py`, or enables the unit. The checked-in
|
||||
unit and [`start-lease-broker.sh`](../../../packages/mosaic/framework/tools/lease-broker/start-lease-broker.sh)
|
||||
are therefore implementation inputs, not live activation authority for this
|
||||
page.
|
||||
|
||||
### Protocol and identity boundary
|
||||
|
||||
The protocol accepts one UTF-8 JSON object followed by one newline, capped at
|
||||
64 KiB. The client must half-close its write side after the newline and before
|
||||
waiting for the response (`shutdown(SHUT_WR)` for POSIX clients or
|
||||
`socket.end()` for Node). Unterminated, multiple, delayed-second, malformed,
|
||||
oversized, or deadline-exceeded requests fail closed. This is an internal Unix
|
||||
socket protocol, not an HTTP/OpenAPI endpoint.
|
||||
|
||||
The broker obtains `(pid, uid, gid)` from kernel `SO_PEERCRED`, binds the
|
||||
session to the anchor's `/proc/<pid>/stat` starttime, and revalidates every
|
||||
walked ancestor's starttime. A caller cannot choose `session_id`; a sibling or
|
||||
unrelated process cannot authenticate with another process's session. A higher
|
||||
runtime generation replaces the prior incarnation and revokes its tokens and
|
||||
lease authority; a lower generation is stale.
|
||||
|
||||
### Lease and tool authorization
|
||||
|
||||
The broker is the sole lease writer. The effective default-deny policy is:
|
||||
|
||||
- Claude read-only classes: `Read`, `Grep`, `Glob`, `Ls`, and `Find`.
|
||||
- Pi read-only classes: `read`, `grep`, `find`, and `ls`.
|
||||
- Both runtimes expose the fixed `mosaic_context_recover` identity as the
|
||||
constrained recovery exception.
|
||||
- Every other built-in, unknown, custom, MCP, shell, edit, write, deployment,
|
||||
provider, or filesystem mutator is consequential and is denied while the
|
||||
session is not `VERIFIED`.
|
||||
|
||||
The normal broker transition is revoke-first and promote-last:
|
||||
|
||||
1. `begin_verification` authenticates the broker-minted session and current
|
||||
generation, revokes existing authority and pending tokens, validates the
|
||||
exact source construction and binding, and enters a pending state.
|
||||
2. The receipt challenge and binding are broker-generated. A trusted observer
|
||||
must provide the exact current-cycle assistant entry; caller-supplied
|
||||
`latest_assistant_message` is rejected on the public broker socket.
|
||||
3. Promotion consumes the evidence-backed one-time token before volatile
|
||||
`VERIFIED` becomes visible. A token or receipt cannot be replayed against a
|
||||
later cycle.
|
||||
4. `revoke_lease`, generation replacement, broker restart, or monotonic TTL
|
||||
expiry removes consequential-tool authority. TTL is positive and capped at
|
||||
300 seconds.
|
||||
|
||||
`launch-runtime.py` is the register-before-`exec` choke point for Claude and
|
||||
Pi. It performs the activation-capability version check, registers the anchor,
|
||||
creates the private generation file, exports the broker identity to descendants,
|
||||
and only then executes the requested runtime. Registration, capability,
|
||||
generation-file, broker-reply, or `exec` failure denies launch. Claude's raw
|
||||
`--dangerously-skip-permissions` flag is owned by this wrapper; callers request
|
||||
only its semantic dangerous mode.
|
||||
|
||||
Claude's all-tools `PreToolUse` hook and Pi's `tool_call` handler submit the
|
||||
runtime-reported tool name to the gate. The gate does not inspect a shell string
|
||||
to decide that one command is safe. Missing identity, malformed input or reply,
|
||||
timeout, broker unavailability, unsafe generation state, and denial all fail
|
||||
closed.
|
||||
|
||||
### Lifecycle and recovery boundaries
|
||||
|
||||
Claude and Pi lifecycle observers use the same authenticated session and
|
||||
broker state machine. Compaction revocation and same-PID replacement behavior
|
||||
are summarized below:
|
||||
|
||||
| Runtime event | Current source-backed behavior |
|
||||
| -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| Claude `PreCompact` | Revoke before compaction; a failed hook blocks the lifecycle transition. |
|
||||
| Claude `SessionStart` matcher `compact` | Revoke again after compacted context starts. |
|
||||
| Claude `SessionStart` matcher `resume\|clear` | Bump the private generation, then revoke the replacement incarnation. |
|
||||
| Pi `session_before_compact` | Revoke before compaction; failure cancels the transition. |
|
||||
| Pi `session_compact` then first `context` | Run one independent post-compaction revoke; a failed post-observer locally blocks later tools until retry. |
|
||||
| Pi `session_start` reason `reload`, `new`, `resume`, or `fork` | Bump the private generation before revoking and reusing the replacement session. |
|
||||
| Fired observer with unavailable broker | Advance the private generation as a local fence and return failure; do not continue consequential work. |
|
||||
|
||||
The [source-resident context-refresh skill](../../../packages/mosaic/framework/skills/mosaic-context-refresh/SKILL.md)
|
||||
is a thin adapter over `recover-context.py`. Recovery begins with a validated
|
||||
normative-fragment construction, broker-side revoke-first transition, and a
|
||||
fresh `PENDING_DELIVERY` challenge. The trusted observer records only finalized
|
||||
Claude Stop-hook or Pi `message_end` content. Completion supplies no receipt or
|
||||
challenge argument; the broker obtains its current challenge, checks the exact
|
||||
observed entry, consumes evidence, and promotes last. Recovery does not accept
|
||||
normal-path receipt text as replayable authority.
|
||||
|
||||
A receipt is only a delivery/liveness prerequisite. It is not a safety,
|
||||
obedience, comprehension, or residency proof. Absent, malformed,
|
||||
prefix-truncated, and observably mutated terminal receipts do not promote. A
|
||||
tail-preserving middle drop is explicitly not receipt-detectable and remains a
|
||||
server-side/T-C residual.
|
||||
|
||||
### Named residual
|
||||
|
||||
If both compaction observers are missed while a lease remains unexpired,
|
||||
consequential tools are **ALLOWED** inside the bounded residual stale window.
|
||||
The mutator gate makes no within-window action-count or timing claim. After the
|
||||
monotonic TTL expires, the next consequential tool is **DENIED**. This is
|
||||
separate from a fired observer that cannot reach the broker, which fails closed
|
||||
through lifecycle cancellation, a generation fence, and/or the Pi local latch.
|
||||
Protected-branch controls and required review/CI remain the irreducible
|
||||
server-side backstop for the T-C total-hook-miss boundary.
|
||||
|
||||
## Held future procedure — non-operative
|
||||
|
||||
There is no current command authority for the following live procedures. The
|
||||
sequence below records source-backed intent for a separately approved
|
||||
activation/recovery work package; it must not be copied into an operator shell.
|
||||
|
||||
### Startup and restart outline (held)
|
||||
|
||||
1. An activation owner would first materialize the exact framework unit,
|
||||
wrapper, and co-located source copies, then verify the resolved parent,
|
||||
socket, state, observer, and generation paths and their no-symlink/private
|
||||
posture.
|
||||
2. The approved supervisor would start the daemon only after confirming that
|
||||
the exact socket path is not owned by another process. `READY` from the
|
||||
daemon and a live Unix socket would be health evidence; a unit file alone
|
||||
would not be healthy.
|
||||
3. A broker crash would require preserving the state file, identifying the
|
||||
socket owner, and making an explicit restart decision. Restart intentionally
|
||||
clears volatile `VERIFIED` leases; it is not a way to restore authority.
|
||||
4. A leftover socket would be handled only after the owning service is
|
||||
confirmed stopped and the exact path is deliberately reviewed. This page
|
||||
supplies no deletion, `systemctl`, enablement, or start command.
|
||||
|
||||
The source's `daemon.py` argument parser and the user unit show how a future
|
||||
activation is wired, but neither source file grants this page authority to
|
||||
invoke that wiring. `applyBrokerSupervisor` is materialization only; the
|
||||
supervisor source explicitly leaves enable/start as a separate held step.
|
||||
|
||||
### Recovery outline (held)
|
||||
|
||||
The future adapter flow is: runtime supplies validated construction and current
|
||||
non-negative epochs; broker performs `begin_recovery` revoke-first and returns
|
||||
one fresh receipt; the adapter delivers that exact receipt; the authenticated
|
||||
observer records the finalized assistant entry; and the adapter requests
|
||||
completion without presenting receipt text or a challenge. Any absent,
|
||||
malformed, stale, duplicated, or mismatched observation leaves the session
|
||||
`UNVERIFIED`; retry starts a new recovery cycle.
|
||||
|
||||
Claude's adapter is restricted to the exact literal recovery argv shape checked
|
||||
by the gate. Pi uses only the registered `mosaic_context_recover` tool; Pi
|
||||
`bash` and all other tools remain gated. Do not manually invoke the revoker to
|
||||
restore authority, send assistant text through the public broker request, or
|
||||
reuse a normal-path receipt. The [context-refresh skill](../../../packages/mosaic/framework/skills/mosaic-context-refresh/SKILL.md)
|
||||
and its [runtime boundary tests](../../../packages/mosaic/src/lease-broker/recovery_runtime_unittest.py)
|
||||
are references for future adapter qualification, not an active operator route.
|
||||
|
||||
### Lease, mutator, and incident handling outline (held)
|
||||
|
||||
- There is no supported operator CLI or HTTP endpoint for sending raw
|
||||
`begin_verification`, `promote_lease`, `revoke_lease`, or `authorize_tool`
|
||||
requests. Do not hand-craft JSON frames, mint tokens, replay receipts, or
|
||||
treat a successful read-only authorization as a promotion.
|
||||
- After a runtime exits, its generation file may be removed only after an
|
||||
approved check establishes that no process for that broker-minted session
|
||||
remains. Retain stale files during incident analysis; they carry no lease
|
||||
authority by themselves.
|
||||
- Corrupt, oversized, symlinked, or non-regular state must be preserved for
|
||||
review and not overwritten in place. Establishing new state is an explicit
|
||||
operational decision that invalidates prior sessions and tokens; no recovery
|
||||
command is supplied here.
|
||||
- Directory `0700` and socket/state `0600` are same-principal hardening only.
|
||||
They do not prevent the same UID from unlinking and replacing a socket. A
|
||||
stronger deployment needs an external protected proxy, ACL, or service
|
||||
boundary that preserves the peer identity required by `SO_PEERCRED` and
|
||||
ancestry checks. No such deployment procedure is current here.
|
||||
|
||||
## Related source and tests
|
||||
|
||||
- [Broker daemon](../../../packages/mosaic/framework/tools/lease-broker/daemon.py)
|
||||
- [Register-and-exec launcher](../../../packages/mosaic/framework/tools/lease-broker/launch-runtime.py)
|
||||
- [Mutator gate](../../../packages/mosaic/framework/tools/lease-broker/mutator-gate.py)
|
||||
- [Recovery command](../../../packages/mosaic/framework/tools/lease-broker/recover-context.py)
|
||||
- [Lease broker acceptance tests](../../../packages/mosaic/src/lease-broker/lease-broker.acceptance.spec.ts)
|
||||
- [Mutator gate acceptance tests](../../../packages/mosaic/src/mutator-gate/mutator-gate.acceptance.spec.ts)
|
||||
- [Pi lifecycle tests](../../../packages/mosaic/src/mutator-gate/pi-compaction-lifecycle.spec.ts)
|
||||
|
||||
This migration changes documentation placement and verified wording only. It does
|
||||
not start or change the broker, a runtime, systemd, PostgreSQL, or any other
|
||||
service.
|
||||
-222
@@ -1,222 +0,0 @@
|
||||
# Mosaic Stack Documentation
|
||||
|
||||
This directory is the canonical home for Mosaic Stack product, architecture, API, operations, and delivery documentation.
|
||||
|
||||
This file is the **documentation contract**. It defines where information belongs, which files are authoritative, how pages connect, and how agents must maintain the documentation set. The structure below is the target structure for the documentation migration; existing content is not considered migrated until it has been classified and moved deliberately.
|
||||
|
||||
## Start here
|
||||
|
||||
Choose the path that matches your purpose:
|
||||
|
||||
- **Understand the product:** start with [`PRD.md`](PRD.md), then use the user guide and the architecture overview.
|
||||
- **Use Mosaic Stack:** use `USER-GUIDE/`.
|
||||
- **Install, configure, deploy, or recover Mosaic Stack:** use `ADMIN-GUIDE/`.
|
||||
- **Change or extend the codebase:** use `DEVELOPER-GUIDE/`.
|
||||
- **Integrate with the gateway:** use `API/`.
|
||||
- **Find a page or follow the documentation graph:** use [`SITEMAP.md`](SITEMAP.md).
|
||||
- **Understand active delivery state:** read [`TASKS.md`](TASKS.md), subject to its single-writer policy.
|
||||
|
||||
The root README is an atlas and authoring guide, not a replacement for the user, administrator, developer, or API books.
|
||||
|
||||
## Canonical directory structure
|
||||
|
||||
The following is the complete target structure. Directories and pages may be created incrementally, but new documentation must use these locations.
|
||||
|
||||
```text
|
||||
docs/
|
||||
├── README.md # this documentation contract and atlas
|
||||
├── PRD.md # canonical requirements source
|
||||
├── TASKS.md # active orchestrator task rollup
|
||||
├── SITEMAP.md # complete navigation index
|
||||
├── .obsidian/ # optional Obsidian vault metadata only
|
||||
│
|
||||
├── USER-GUIDE/ # end-user documentation
|
||||
│ ├── README.md # user-book index
|
||||
│ ├── getting-started/ # first install/use and quickstarts
|
||||
│ ├── concepts/ # user-facing concepts and terminology
|
||||
│ ├── workflows/ # task-oriented user procedures
|
||||
│ └── troubleshooting/ # user-visible failures and fixes
|
||||
│
|
||||
├── ADMIN-GUIDE/ # operator and administrator documentation
|
||||
│ ├── README.md # admin-book index
|
||||
│ ├── installation/ # installation and prerequisites
|
||||
│ ├── configuration/ # configuration and environment
|
||||
│ ├── deployment/ # deployment topologies and rollout
|
||||
│ ├── operations/ # routine operation and observability
|
||||
│ ├── security/ # auth, RBAC, secrets, and security controls
|
||||
│ └── recovery/ # incident response, backup, and recovery
|
||||
│
|
||||
├── DEVELOPER-GUIDE/ # contributor and maintainer documentation
|
||||
│ ├── README.md # developer-book index
|
||||
│ ├── architecture/ # system model and technical design
|
||||
│ │ ├── README.md # architecture index
|
||||
│ │ ├── system-overview.md # platform boundary and major flows
|
||||
│ │ ├── component-map.md # apps, packages, plugins, and dependencies
|
||||
│ │ ├── data-flow.md # data, event, and control-plane movement
|
||||
│ │ ├── security-model.md # trust boundaries and authority model
|
||||
│ │ ├── decisions/ # ADRs and approved design decisions
|
||||
│ │ └── rfcs/ # proposals and protocol RFCs
|
||||
│ ├── packages/ # package- and application-level guides
|
||||
│ ├── local-development/ # local setup and safe development routes
|
||||
│ ├── testing/ # test strategy and verification workflow
|
||||
│ ├── contributing/ # contribution and review workflow
|
||||
│ └── integrations/ # plugin, provider, and adapter authoring
|
||||
│
|
||||
├── API/ # machine- and human-readable API contract
|
||||
│ ├── README.md # API documentation index
|
||||
│ ├── OPENAPI.yaml # canonical OpenAPI contract
|
||||
│ └── ENDPOINTS.md # endpoint, auth, permission, and error index
|
||||
│
|
||||
├── assets/ # diagrams and documentation media
|
||||
├── reports/ # evidence and findings; never normative by itself
|
||||
│ ├── code-review/ # review reports
|
||||
│ ├── documentation/ # documentation audits and checklists
|
||||
│ ├── qa/ # QA and verification reports
|
||||
│ ├── security/ # security reviews and threat evidence
|
||||
│ └── deferred/ # unresolved or explicitly deferred findings
|
||||
├── tasks/ # archived task snapshots and learnings
|
||||
├── plans/ # approved design and implementation plans
|
||||
├── scratchpads/ # active task-specific working notes
|
||||
├── releases/ # release notes and compatibility notes
|
||||
├── archive/ # superseded but intentionally retained docs
|
||||
└── _old_structure/ # temporary read-only migration quarantine
|
||||
```
|
||||
|
||||
### Directory rules
|
||||
|
||||
- `.obsidian/` is optional tool metadata. It is not a content directory. Do not put Markdown pages, reports, plans, task notes, or source-of-truth files there.
|
||||
- `USER-GUIDE/`, `ADMIN-GUIDE/`, and `DEVELOPER-GUIDE/` are books. Each book must have a `README.md` that links to every chapter and page in that book.
|
||||
- Each chapter is a directory for one topic area. Each page should cover one concern or workflow.
|
||||
- `API/OPENAPI.yaml` is the API contract. `API/ENDPOINTS.md` explains details that OpenAPI cannot fully express.
|
||||
- `reports/`, `tasks/`, `plans/`, `scratchpads/`, `releases/`, and `archive/` are artifact boundaries, not alternative guide books.
|
||||
- `_old_structure/` is temporary migration quarantine. It is read-only, is not current documentation, and is never a destination for new work.
|
||||
- `docs/mosaic-stack/` is retired as a content boundary. Do not create new files there. Cross-cutting architecture belongs in `DEVELOPER-GUIDE/architecture/` and navigation belongs here and in `SITEMAP.md`.
|
||||
- Do not add miscellaneous Markdown files directly under `docs/`. The permitted root files are `README.md`, `PRD.md`, `TASKS.md`, and `SITEMAP.md`; all other content belongs in a scoped directory.
|
||||
|
||||
## Where agents must place documents
|
||||
|
||||
Classify a document by its primary reader and purpose before creating it. Use this matrix instead of guessing from an existing filename.
|
||||
|
||||
| Content | Required location | Examples |
|
||||
| -------------------------------------------------------------------------- | ---------------------------------------------------------------------- | --------------------------------------------------------- |
|
||||
| Documentation contract and top-level map | `docs/README.md` | Folder rules, source-of-truth policy, authoring workflow |
|
||||
| Product requirements and acceptance criteria | `docs/PRD.md` or an explicitly scoped workstream PRD | Objectives, scope, requirements, acceptance criteria |
|
||||
| Active orchestrator task state | `docs/TASKS.md` | Milestone/task rollup; single writer is the orchestrator |
|
||||
| Documentation navigation | `docs/SITEMAP.md` and the relevant book `README.md` | Page indexes and reader paths |
|
||||
| User-visible workflow or troubleshooting | `docs/USER-GUIDE/<chapter>/` | Chat, projects, task workflows, user setup |
|
||||
| Installation, configuration, deployment, operations, security, or recovery | `docs/ADMIN-GUIDE/<chapter>/` | SSO, tiers, secrets, health checks, incident runbooks |
|
||||
| Architecture, component map, data flow, package design, ADR, or RFC | `docs/DEVELOPER-GUIDE/architecture/` or its relevant developer chapter | System design, protocol decisions, package contracts |
|
||||
| Local development, testing, contribution, or integration authoring | `docs/DEVELOPER-GUIDE/<chapter>/` | Setup, test commands, plugin development |
|
||||
| HTTP/WebSocket API contract | `docs/API/OPENAPI.yaml` and `docs/API/ENDPOINTS.md` | Paths, schemas, auth, permissions, errors |
|
||||
| Diagram, screenshot, or other documentation media | `docs/assets/` or an owning chapter's asset directory | Architecture diagrams, workflow images |
|
||||
| Approved design or implementation plan | `docs/plans/` | Design docs and task-by-task execution plans |
|
||||
| Active task working notes and verification log | `docs/scratchpads/<task-id>-<slug>.md` | Assumptions, progress, commands, evidence, blockers |
|
||||
| Code review, QA, audit, security, or deferral evidence | `docs/reports/<category>/` | Review findings, test reports, security evidence |
|
||||
| Archived task snapshot or orchestrator learning | `docs/tasks/` | Closed task breakdowns and retained learnings |
|
||||
| Release notes or version-specific compatibility information | `docs/releases/` | Release summaries, upgrade notes, deprecations |
|
||||
| Superseded documentation that must remain discoverable | `docs/archive/` | Historical guides, retired proposals, old mission records |
|
||||
|
||||
If content seems to fit multiple locations, choose one canonical home and link to it from the other relevant indexes. Do not create copies merely to satisfy multiple audiences.
|
||||
|
||||
## Source-of-truth and precedence
|
||||
|
||||
Use these rules when documents disagree:
|
||||
|
||||
1. **Requirements:** `PRD.md` is the project requirements source. A scoped PRD may add detail, but must link to and remain consistent with the root PRD.
|
||||
2. **Active work state:** `TASKS.md` is the active orchestrator rollup. Workers read it; they do not rewrite its status or schema unless the orchestrator authorizes that change.
|
||||
3. **API:** `API/OPENAPI.yaml` is the machine-readable API contract. `ENDPOINTS.md` is the human index and may explain constraints not represented by OpenAPI.
|
||||
4. **Current behavior:** guide pages describe verified current behavior. If implementation changes, update the affected guide in the same logical change set.
|
||||
5. **Architecture and decisions:** approved decisions under `DEVELOPER-GUIDE/architecture/decisions/` and RFCs explain why the system has its current shape. They do not silently override the PRD or API contract.
|
||||
6. **Evidence:** reports record what was reviewed, tested, or deferred. They are evidence, not a substitute for current requirements or operational instructions.
|
||||
7. **Plans:** plans describe intended work. After delivery, update the canonical guide, contract, or decision page rather than treating the plan as the current behavior.
|
||||
8. **Scratchpads:** scratchpads are working memory and verification records. They are not product documentation and must not become hidden requirements.
|
||||
9. **Archive:** archived pages are historical. Every retained page should identify its status and replacement, if one exists.
|
||||
10. **Code is authoritative for executable behavior:** documentation must not claim commands, paths, APIs, or safety properties that the current code and tests do not support. When the desired behavior differs from current behavior, record the desired behavior in the PRD or an approved design and label operational procedures as held/non-operative when necessary.
|
||||
|
||||
## Page conventions
|
||||
|
||||
Every canonical page should:
|
||||
|
||||
1. Use a descriptive lowercase kebab-case filename, except for established root control files and required API filenames.
|
||||
2. Cover one concern, concept, decision, or workflow.
|
||||
3. Start with a clear title and a short purpose statement.
|
||||
4. Identify its audience and lifecycle status when it is more than a simple index.
|
||||
5. State prerequisites, dependencies, and source-of-truth references.
|
||||
6. Mark examples and commands as current, illustrative, held, or non-operative when that distinction matters.
|
||||
7. Include an owner or maintenance responsibility for operationally sensitive content.
|
||||
8. Link to the relevant book index and related canonical pages.
|
||||
|
||||
Recommended front matter for canonical pages:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: Human-readable page title
|
||||
type: guide
|
||||
audience: developer
|
||||
status: current
|
||||
source_of_truth: false
|
||||
---
|
||||
```
|
||||
|
||||
Allowed `type` values include `guide`, `concept`, `reference`, `decision`, `rfc`, and `runbook`. Allowed `audience` values are `user`, `admin`, `developer`, and `all`. Allowed `status` values are `current`, `draft`, `deprecated`, and `historical`.
|
||||
|
||||
Indexes may omit front matter when their purpose is self-evident. A page with normative authority must explicitly identify the authority it owns and the boundaries of that authority.
|
||||
|
||||
## Obsidian and link conventions
|
||||
|
||||
Mosaic Stack documentation is compatible with Obsidian without making Git-hosted navigation unusable.
|
||||
|
||||
- Use Obsidian wikilinks for graph-oriented internal relationships, for example `[[DEVELOPER-GUIDE/architecture/component-map|Component map]]`.
|
||||
- Use normal relative Markdown links in `SITEMAP.md` and book `README.md` indexes so links render on Gitea/GitHub and other Markdown hosts. Obsidian resolves these links too.
|
||||
- Use `Related`, `Depends on`, and `Referenced by` sections when a page has meaningful relationships to other pages.
|
||||
- Use wikilink heading targets when a specific section matters, for example `[[DEVELOPER-GUIDE/architecture/system-overview#Gateway boundary|Gateway boundary]]`.
|
||||
- Omit `.md` in wikilinks. Use an alias when the path is not a readable label.
|
||||
- Use standard Markdown links for external URLs, source files, commands, and API paths.
|
||||
- Link to stable repository-relative paths, not temporary branches, line numbers, or machine-local paths.
|
||||
- Every current canonical page must be reachable from a book index or `SITEMAP.md`; do not create orphan pages.
|
||||
- Do not use `_old_structure/` links as current navigation. Historical references must explain why the page is retained and point to its replacement.
|
||||
|
||||
## Authoring workflow for agents
|
||||
|
||||
For every documentation change:
|
||||
|
||||
1. **Search first.** Look for an existing page, requirement, report, task, or scratchpad before creating a new file.
|
||||
2. **Classify.** Choose the primary audience, content type, lifecycle status, and source-of-truth role.
|
||||
3. **Choose the canonical home.** Apply the placement matrix; do not place content in the docs root or `docs/mosaic-stack/`.
|
||||
4. **Write one concern.** Keep the page focused and link to existing pages instead of copying them.
|
||||
5. **Connect the page.** Add it to the owning book index and `SITEMAP.md`; add `Related`, `Depends on`, or `Referenced by` links where useful.
|
||||
6. **Record non-trivial work.** Create or update `docs/scratchpads/<task-id>-<slug>.md` with objective, assumptions, progress, commands, risks, and evidence. Active `docs/TASKS.md` changes remain under its single-writer policy.
|
||||
7. **Verify claims.** Check commands, paths, API schemas, permissions, and status against source and tests. Label held or non-operative procedures explicitly.
|
||||
8. **Format and review.** Run the repository's Markdown formatting check, inspect links and headings, and review the diff for stale paths or duplicated authority.
|
||||
9. **Commit a coherent change.** Keep documentation changes with the related code/API/operation change when applicable, and do not include unrelated staged files.
|
||||
|
||||
## Migration policy
|
||||
|
||||
The initial structure pass defined the target structure without moving or rewriting the existing documentation set. Subsequent migration slices may move or rewrite classified pages deliberately, with repository references and indexes updated together.
|
||||
|
||||
- Treat `_old_structure/` as read-only migration quarantine. Do not add new content there.
|
||||
- Treat the current root-level legacy pages (`openapi-tess.yaml` and the task/mission documents) as migration backlog, not permission to create more root files. The former empty `QUICKSTART.md` placeholder now lives as `USER-GUIDE/getting-started/quickstart.md`; the verified SSO runbook lives under `ADMIN-GUIDE/security/`; historical evidence such as the P8-003 performance report belongs under `reports/qa/`.
|
||||
- Candidate destinations include `USER-GUIDE/getting-started/`, `ADMIN-GUIDE/security/`, `DEVELOPER-GUIDE/architecture/`, `API/`, `tasks/`, `plans/`, and `archive/`; classify each page before moving it.
|
||||
- `docs/fleet/` is an executable documentation contract consumed by current source and tests; keep that complete book at its canonical path. Federation and other authority surfaces may also have live consumers. Update any such path only through an explicitly coordinated source/test and authority migration.
|
||||
- When a page is moved, update all repository links, source comments, tests, book indexes, and `SITEMAP.md` in the same logical change.
|
||||
- Preserve historical evidence in `reports/`, `tasks/`, `releases/`, or `archive/` instead of mixing it into current guides.
|
||||
- Remove the empty `docs/mosaic-stack/` boundary only after confirming no source, test, or documentation reference requires it.
|
||||
- Remove `_old_structure/` only after migration verification proves that current navigation and required historical retention are intact.
|
||||
|
||||
## Current transition state
|
||||
|
||||
Classified migration is active and the audience books now contain verified current pages. During this transition:
|
||||
|
||||
- The target directories listed above remain the placement contract; some planned chapters are not populated yet.
|
||||
- `docs/_old_structure/` remains available for migration evidence but is not current documentation or command authority.
|
||||
- `docs/fleet/`, `docs/native-kanban-sot/`, `docs/requirements/native-kanban-sot.md`, and the KBN-101 hold-site documents remain at their canonical paths because they are active executable or authority surfaces. Their placement cannot change through documentation-only cleanup.
|
||||
- Root control and API artifacts remain until their authority and destination decisions are approved.
|
||||
- `docs/SITEMAP.md` contains only resolvable current navigation plus a non-linked summary of authority-gated migration groups.
|
||||
- No external publishing platform is assumed. The canonical source remains this repository under `docs/`.
|
||||
|
||||
## Current migration boundaries
|
||||
|
||||
- Do not bulk-promote or bulk-rewrite quarantined documentation; classify and verify each coherent slice.
|
||||
- Do not rewrite product requirements, orchestrator-owned task state, mission status, or the API contract without the required authority decision.
|
||||
- Do not create a documentation website or publishing pipeline as part of content migration.
|
||||
- Do not treat Obsidian metadata as product or project source of truth.
|
||||
+80
-74
@@ -1,97 +1,103 @@
|
||||
# Documentation Sitemap
|
||||
|
||||
> **Status:** Current navigation index. Quarantined and authority-gated material is summarized without being presented as current guidance.
|
||||
## Compaction refresh lease broker
|
||||
|
||||
## Start here
|
||||
- [Internal broker protocol](architecture/lease-broker-protocol.md) — kernel identity, ancestry and generation invariants, framed requests, responses, and persisted cycle bindings.
|
||||
- [Broker operations](guides/lease-broker-operations.md) — protected paths, startup, constrained recovery, fail-closed posture, distinct-principal deployment, and residual risk.
|
||||
- [Constrained recovery skill](../packages/mosaic/framework/skills/mosaic-context-refresh/SKILL.md) — source-resident thin wrapper, receipt scope, C4 replay boundary, and T-C middle-drop disclosure.
|
||||
- [Lease-broker security notes](architecture/lease-broker-security.md) — identity, whole-class authorization, threat boundaries, and coordinator review requirements.
|
||||
- [Whole mutator-class gate](architecture/mutator-class-gate.md) — default-deny policy, revoke-first/promote-last state machine, TTL, runtime adapters, and T-B/T-C assurance boundary.
|
||||
- [Compaction revocation lifecycle](architecture/compaction-revocation.md) — Claude/Pi observer matrix, same-PID generation rollover, failure fencing, and the named bounded residual stale window.
|
||||
|
||||
- [Documentation atlas](README.md) — placement, source-of-truth, linking, and migration rules.
|
||||
- [User guide](USER-GUIDE/README.md) — end-user workflows and product behavior.
|
||||
- [Administrator guide](ADMIN-GUIDE/README.md) — installation, configuration, operations, security, and recovery.
|
||||
- [Developer guide](DEVELOPER-GUIDE/README.md) — architecture, testing, integrations, and contributor material.
|
||||
- [API documentation](API/README.md) — API contract migration status.
|
||||
- [Reports index](reports/README.md) — review, audit, QA, security, and retained evidence.
|
||||
- [Archive index](archive/README.md) — superseded historical pages.
|
||||
## CLI and skill management
|
||||
|
||||
## Product and delivery control
|
||||
- [Skill registration user guide](guides/user-guide.md#claude-code-skill-registration) — register, unregister, list statuses, automatic install/update reconciliation, and Claude reload behavior.
|
||||
- [Skill bridge developer guide](guides/dev-guide.md#claude-code-skill-bridge) — path-validation, ownership, clobber-protection, install/update wiring, tests, and Pi/Codex scope notes.
|
||||
|
||||
- [Product requirements](PRD.md) — normative requirements; currently marked draft and retaining authority-gated legacy references.
|
||||
- [Active task rollup](TASKS.md) — orchestrator-owned work state; workers do not modify it.
|
||||
- [MVP mission manifest](MISSION-MANIFEST.md) — control-plane mission rollup; activity and status remain under its authorized owner.
|
||||
- [Documentation catalog and truth audit](reports/documentation/2026-08-10-docs-catalog-audit.md) — complete baseline inventory, evidence labels, broken-link clusters, and migration recommendations.
|
||||
## Fleet configuration management
|
||||
|
||||
## Protected current authority and executable books
|
||||
- [Fleet configuration entry point](fleet/README.md) — desired-versus-observed decision tree and complete operator link map.
|
||||
- [Desired, derived, and observed state](fleet/concepts/desired-vs-observed-state.md) — roster authority, generation, ownership, and drift.
|
||||
- [Identity, class, and runtime](fleet/concepts/identity-class-runtime.md) — stable name, display alias, class, runtime, provider, and model separation.
|
||||
- [Role authority and leases](fleet/concepts/role-authority-and-leases.md) — validator/merge-gate separation and bounded lease authority.
|
||||
- [Generated launch chain](fleet/concepts/generated-env-launch-chain.md) — strict data parsing, precedence, and quarantine.
|
||||
- [Roster v2 structural contract](fleet/reference/roster-v2-fields.md) — schema, supported values, required fields, defaults, and constraints.
|
||||
- [Fleet CLI reference](fleet/reference/cli.md) — local desired-state commands, JSON/exit behavior, and gateway-catalog separation.
|
||||
- [Lifecycle transitions](fleet/reference/lifecycle-transitions.md) — create/apply/reboot/migration/rollback boundaries.
|
||||
- [Status and drift](fleet/reference/status-and-drift.md) — desired/managed/observed state and current/future classifications.
|
||||
- [Safe agent CRUD](fleet/how-to/create-update-delete-agent.md) — expected generation, dry-run, and partial-failure recovery.
|
||||
- [Local lifecycle operations](fleet/how-to/start-stop-restart.md) — persisted versus one-shot actions.
|
||||
- [Configurable interaction instance](fleet/how-to/configure-tess-interaction.md) and [validator instance](fleet/how-to/configure-ultron-validator.md) — generic identities and protected limits.
|
||||
- [Reconcile and recover](fleet/operations/reconcile-and-recover.md) — plan/apply lock and recovery behavior.
|
||||
- [Environment quarantine](fleet/operations/env-quarantine.md) — private evidence and value-free diagnostics.
|
||||
- [Systemd/tmux troubleshooting](fleet/operations/systemd-tmux-troubleshooting.md) — socket, holder, unmanaged-session, and lock decisions.
|
||||
- [Backup/restore boundary](fleet/operations/backup-restore.md) and [upgrade-assets hold](fleet/operations/upgrade-assets.md).
|
||||
- [v1-to-v2 migration preview](fleet/migration/v1-to-v2.md) and [executable artifact dispositions](fleet/migration/example-profile-disposition.md).
|
||||
- [FCM M5 closure evidence](reports/documentation/758-fleet-config-ia-closure.md) and [approved deferrals](reports/deferred/758-fleet-config-deferrals.md).
|
||||
|
||||
These paths remain canonical because current source/tests consume them or because the KBN authority process protects them. Relocation requires an explicitly coordinated authority and consumer migration, not documentation-only cleanup.
|
||||
## Official channel plugins
|
||||
|
||||
- [Fleet configuration management](fleet/README.md) — executable roster-v2 operator book, schema, examples, and north-star projections.
|
||||
- [Fleet local canary](guides/fleet-local-canary.md) — protected Fleet validation procedure referenced by the current developer hold-site guide.
|
||||
- [Native Kanban/SOT index](native-kanban-sot/INDEX.md) — active canonical KBN contract and workstream index.
|
||||
- [Native Kanban/SOT requirements](requirements/native-kanban-sot.md) — active ratified requirements surface.
|
||||
- [KBN-101 database role split](native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md) — active held database authority contract.
|
||||
- [Developer hold-site guide](guides/dev-guide.md) — protected current KBN-101 development boundary.
|
||||
- [Deployment hold-site guide](guides/deployment.md) — protected, non-operative PostgreSQL/deployment boundary.
|
||||
- [Tier-migration hold-site guide](guides/migrate-tier.md) — protected secure migration route and hold boundary.
|
||||
- [Federation setup hold site](federation/SETUP.md) — protected KBN-101 setup boundary; follow its explicit holds.
|
||||
- [Channel protocol architecture](architecture/channel-protocol.md) — shared lifecycle, message, stable-route, authorization, and response-target contracts.
|
||||
- [Discord administrator configuration](guides/admin-guide.md#discord-ingress-security) — secrets, allowlists, bindings, role policy, and thread permissions.
|
||||
- [Discord user workflow](tess/USER-GUIDE.md#discord-conversations) — in-channel messages, mention-created threads, and runtime-transparent continuity.
|
||||
- [Channel plugin authoring](tess/PLUGIN-GUIDE.md#official-channel-adapter-contract) — requirements for future Matrix, Slack, and other official adapters.
|
||||
- [Discord package guide](../plugins/discord/README.md) — package behavior, configuration shape, and development commands.
|
||||
|
||||
## User documentation
|
||||
## Native Kanban and canonical task SOT
|
||||
|
||||
- [Quickstart](USER-GUIDE/getting-started/quickstart.md) — installed-CLI first-use route with local PGlite safety boundaries.
|
||||
- [Web dashboard](USER-GUIDE/product/web-dashboard.md) — current routes, views, chat persistence, settings, and admin behavior.
|
||||
- [Discord conversations](USER-GUIDE/workflows/discord-conversations.md) — current authorized parent-channel, thread, attachment, and control workflow.
|
||||
- [Canonical requirements](requirements/native-kanban-sot.md) — ratified P0–P3 requirements and acceptance criteria.
|
||||
- [Workstream index](native-kanban-sot/INDEX.md) — artifact map, lane partition, and delivery order.
|
||||
- [Mission manifest](native-kanban-sot/MISSION-MANIFEST.md) — scope, authority, invariants, and gate model.
|
||||
- [Task decomposition](native-kanban-sot/TASKS.md) — dependency-ordered implementation slices and ownership boundaries.
|
||||
- [KBN-101 database role split](native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md) — rc.16 direct-Drizzle storage-wrapper hold: legacy N-1/uncertified/non-operative pending -02/-03/-06/-08; exact README/user-guide wrapper forms fail before masking and source-consistency rejects runner-delegation copy; held bootstrap → TLS/roles → run → verify → readiness; plus prior attestation, pgvector owner, classifier, TLS, activation, and certification prerequisite.
|
||||
- [Federated tier data migration](guides/migrate-tier.md) — active KBN-101-07 operator route: runner-produced target attestation, dedicated non-DDL importer, and paired credential-/attestation-file references only.
|
||||
- [Frozen shared contract](native-kanban-sot/SHARED-CONTRACT.md) — schema, API, Coordinator, health, recovery, and migration contracts.
|
||||
- [KBN-101 exact-head security review](reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md) — retained prior REQUEST CHANGES evidence for `da742ca`; rc.16 awaits independent exact-head re-review after closing the current generic storage-wrapper authority HIGH finding.
|
||||
- [Initial independent review](reports/native-kanban-sot/canon-initial-review-no-go.md) — KCR-001–016 findings that blocked the first draft.
|
||||
- [Final independent re-review](reports/native-kanban-sot/canon-final-rereview-go.md) — closure evidence and GO verdict.
|
||||
- [Ultron final gate](reports/native-kanban-sot/ultron-final-go.md) — final requirements, authority, schema, migration, recovery, and evidence review.
|
||||
|
||||
## Administrator documentation
|
||||
## Tess interaction agent
|
||||
|
||||
- [Administrator operations](ADMIN-GUIDE/operations/README.md) — current local procedures and explicitly held outlines.
|
||||
- [Upgrade safety and recovery](ADMIN-GUIDE/operations/upgrade-safety-and-recovery.md) — installed-CLI/local-PGlite upgrade and framework recovery.
|
||||
- [Mos connector lease operations](ADMIN-GUIDE/operations/mos-connector-lease-operations.md) — held/non-operative M1 outline while policy remains deny-all.
|
||||
- [Administrator security](ADMIN-GUIDE/security/README.md) — current security chapter index.
|
||||
- [SSO providers](ADMIN-GUIDE/security/sso-providers.md) — Authentik, WorkOS, and Keycloak configuration and discovery.
|
||||
- [Discord ingress security](ADMIN-GUIDE/security/discord-ingress.md) — service authentication, allowlists, bindings, roles, replay, and failure controls.
|
||||
### Operator guides
|
||||
|
||||
## Developer documentation
|
||||
- [User guide](tess/USER-GUIDE.md) — authorized session, attach, send, stop, and handoff workflows.
|
||||
- [Admin guide](tess/ADMIN-GUIDE.md) — deployment configuration, policy, and approval controls.
|
||||
- [Developer guide](tess/DEVELOPER-GUIDE.md) — provider contracts, scope boundaries, and test workflow.
|
||||
- [Plugin guide](tess/PLUGIN-GUIDE.md) — adapter, redaction, and identity-as-data requirements.
|
||||
- [Operations guide](tess/OPERATIONS-GUIDE.md) — readiness, recovery, and incident-safe procedures.
|
||||
|
||||
- [Architecture index](DEVELOPER-GUIDE/architecture/README.md) — current architecture contracts, decisions, and draft RFCs.
|
||||
- [Channel protocol](DEVELOPER-GUIDE/architecture/channel-protocol.md) — shared DTOs and current Discord compatibility boundary; future adapters are draft.
|
||||
- [Lease-broker protocol](DEVELOPER-GUIDE/architecture/lease-broker-protocol.md) — authenticated Unix-socket protocol and persistence boundary.
|
||||
- [Lease-broker security](DEVELOPER-GUIDE/architecture/lease-broker-security.md) — identity, ancestry, filesystem, observer, and residual boundaries.
|
||||
- [Whole mutator-class gate](DEVELOPER-GUIDE/architecture/mutator-class-gate.md) — default-deny tool authorization and launch choke point.
|
||||
- [Compaction revocation](DEVELOPER-GUIDE/architecture/compaction-revocation.md) — lifecycle observers, generation fencing, and residual stale window.
|
||||
- [Architecture decisions](DEVELOPER-GUIDE/architecture/decisions/README.md) — implemented and accepted boundaries.
|
||||
- [Mos runtime portability M1](DEVELOPER-GUIDE/architecture/decisions/mos-runtime-portability-m1.md) — logical identity, connector lease, grants, audit, and fencing.
|
||||
- [Architecture RFCs](DEVELOPER-GUIDE/architecture/rfcs/README.md) — draft proposals without operational authority.
|
||||
- [Optional AI egress gateways](DEVELOPER-GUIDE/architecture/rfcs/optional-ai-egress-gateways.md) — draft proposal; LiteLLM and Bifrost are not integrated.
|
||||
- [Lease-broker operations and verification](DEVELOPER-GUIDE/testing/lease-broker-operations.md) — safe static/test workflow; live procedures remain held.
|
||||
- [Channel adapter authoring](DEVELOPER-GUIDE/integrations/channel-adapters.md) — current shared contract and Discord reference boundary.
|
||||
### Architecture and security
|
||||
|
||||
## API transition
|
||||
- [Architecture](tess/ARCHITECTURE.md)
|
||||
- [Threat model](tess/THREAT-MODEL.md)
|
||||
- [Mos coordination boundary](tess/MOS-COORDINATION.md)
|
||||
- [Hermes runtime adapter design](tess/hermes-runtime-adapter-design.md)
|
||||
- [Operator plugin sketch](tess/M4-003-OPERATOR-PLUGIN-SKETCH.md)
|
||||
|
||||
- [API index](API/README.md) — consolidated gateway contract remains planned.
|
||||
- [Legacy Tess-scoped OpenAPI contract](openapi-tess.yaml) — valid OpenAPI 3.1 artifact with incomplete gateway coverage; canonical scope requires maintainer approval.
|
||||
### API contract
|
||||
|
||||
## Evidence and planning
|
||||
- [Tess OpenAPI contract](openapi-tess.yaml)
|
||||
|
||||
- [Reports index](reports/README.md) — all tracked report categories and evidence boundaries.
|
||||
- [Archived missions](archive/missions/README.md) — historical CLI, harness, install UX, and storage-abstraction delivery records.
|
||||
- [Archived planning](archive/planning/README.md) — historical briefs, board reviews, and work-package specifications.
|
||||
- [Archived work records](archive/work-records/README.md) — historical task scratchpads without live consumers.
|
||||
- [P8-003 performance report](reports/qa/p8-003-performance-optimization.md) — historical implementation evidence, not a current SLO.
|
||||
- [Plans index](plans/README.md) — approved intent and implementation/audit plans.
|
||||
- [Documentation information-architecture design](plans/2026-08-10-docs-information-architecture-design.md) — approved documentation structure decision.
|
||||
- [Documentation catalog-audit plan](plans/2026-08-10-docs-catalog-audit.md) — evidence method and migration acceptance criteria.
|
||||
- [Scratchpads index](scratchpads/README.md) — working memory and verification records.
|
||||
- [Documentation migration scratchpad](scratchpads/DOCS-IA-002-catalog-audit.md) — coordinator progress, verification, and resumability record.
|
||||
### Migration and qualification
|
||||
|
||||
## Authority-gated migration backlog
|
||||
- [Migration inventory](tess/M5-MIGRATION-INVENTORY.md)
|
||||
- [Cutover procedure](tess/M5-MIGRATION-CUTOVER.md)
|
||||
- [Rollback procedure](tess/M5-MIGRATION-ROLLBACK.md)
|
||||
- [Retention and deprecation evidence](tess/M5-MIGRATION-RETENTION-DEPRECATION.md)
|
||||
- [Verification matrix](tess/VERIFICATION-MATRIX.md)
|
||||
- [Documentation checklist](tess/M5-003-DOCUMENTATION-CHECKLIST.md)
|
||||
- [Independent Option 2 runtime-portability qualification (2026-07-14)](tess/qualification/2026-07-14-option2-runtime-portability.md)
|
||||
|
||||
The complete file-level backlog remains in the [documentation catalog](reports/documentation/2026-08-10-docs-catalog-audit.md). The groups below are intentionally not linked as current pages:
|
||||
## Runtime-neutral Mos portability
|
||||
|
||||
- **Fleet configuration:** the executable book is restored at `docs/fleet/`; any future audience-book relocation requires coordinated source/test and authority migration.
|
||||
- **Federation:** the protected KBN-101 setup hold site remains canonical; disposition of the rest of the workstream requires maintainer/orchestrator confirmation.
|
||||
- **Native Kanban/KBN-101:** active SSOT, requirements, and hold-site documents remain canonical; task state and future placement require product-owner, Task-18, and orchestrator decisions.
|
||||
- **Tess:** mixed user, administrator, developer, migration, qualification, and API material requires audience splitting and a decision on active versus historical status.
|
||||
- **Gateway API:** the Tess-scoped OpenAPI artifact must not be renamed into the canonical full-gateway contract until scope, authentication, errors, schemas, and transport coverage are approved.
|
||||
- **Deployment and tier migration:** PostgreSQL, federated, bare-metal, Compose, Gateway/Web activation, and migration-runner procedures remain held under the repository safety policy.
|
||||
- **Mixed legacy guides and scratchpads:** remaining records are coupled to control documents, tests/fixtures, mission evidence, or held procedures; migrate them with their owners.
|
||||
- **Compaction-refresh probes:** scripts are Mos-gated and path-coupled; do not move or execute them as documentation cleanup.
|
||||
- [Optional AI egress gateway ADR](architecture/ADR-MOS-EGRESS-GATEWAYS.md) — placement and gates for LiteLLM, Bifrost, and purpose-built translation proxies.
|
||||
- [Runtime-neutral Mos identity and failover mission](https://git.mosaicstack.dev/mosaicstack/stack/issues/754)
|
||||
- [Logical identity and connector lease/fencing implementation](https://git.mosaicstack.dev/mosaicstack/stack/issues/755)
|
||||
- [M1 logical identity and fencing architecture](architecture/mos-runtime-portability-m1.md)
|
||||
- [M1 connector lease operations](guides/mos-connector-lease-operations.md)
|
||||
|
||||
`docs/_old_structure/` remains read-only migration quarantine. It is not current navigation and must not be used as command authority.
|
||||
## Comms evolution — Matrix-native MACP (design, draft)
|
||||
|
||||
- [RFC-001 — MACP: a Mosaic-native, Matrix-native comms layer](rfcs/RFC-001-MACP-MATRIX-NATIVE.md) — Synapse + Mosaic appservice backbone, MACP v1 protocol, presence/escalation, federation, strangler migration off the Hermes MCP bridge.
|
||||
- [RFC-002 — Install, configuration & topology for the Matrix/MACP comms system](rfcs/RFC-002-INSTALL-CONFIG-TOPOLOGY.md) — open-source install topology modes, ACME cert provisioning, pluggable secret backend, and config precedence.
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
# SSO Providers
|
||||
|
||||
Mosaic Stack supports optional enterprise single sign-on through Better Auth's generic OAuth flow. The gateway mounts Better Auth under `/api/auth`, so every provider callback terminates at:
|
||||
|
||||
```text
|
||||
{BETTER_AUTH_URL}/api/auth/oauth2/callback/{providerId}
|
||||
```
|
||||
|
||||
For the providers in this document:
|
||||
|
||||
- Authentik: `{BETTER_AUTH_URL}/api/auth/oauth2/callback/authentik`
|
||||
- WorkOS: `{BETTER_AUTH_URL}/api/auth/oauth2/callback/workos`
|
||||
- Keycloak: `{BETTER_AUTH_URL}/api/auth/oauth2/callback/keycloak`
|
||||
|
||||
## Required environment variables
|
||||
|
||||
### Authentik
|
||||
|
||||
```bash
|
||||
AUTHENTIK_ISSUER=https://auth.example.com/application/o/mosaic
|
||||
AUTHENTIK_CLIENT_ID=...
|
||||
AUTHENTIK_CLIENT_SECRET=...
|
||||
```
|
||||
|
||||
### WorkOS
|
||||
|
||||
```bash
|
||||
WORKOS_ISSUER=https://your-company.authkit.app
|
||||
WORKOS_CLIENT_ID=client_...
|
||||
WORKOS_CLIENT_SECRET=...
|
||||
NEXT_PUBLIC_WORKOS_ENABLED=true
|
||||
```
|
||||
|
||||
`WORKOS_ISSUER` should be the WorkOS AuthKit issuer or custom auth domain, not the raw REST API hostname. Mosaic derives the OIDC discovery URL from that issuer.
|
||||
|
||||
### Keycloak
|
||||
|
||||
```bash
|
||||
KEYCLOAK_ISSUER=https://auth.example.com/realms/master
|
||||
KEYCLOAK_CLIENT_ID=mosaic
|
||||
KEYCLOAK_CLIENT_SECRET=...
|
||||
NEXT_PUBLIC_KEYCLOAK_ENABLED=true
|
||||
```
|
||||
|
||||
If you prefer, you can keep the issuer split as:
|
||||
|
||||
```bash
|
||||
KEYCLOAK_URL=https://auth.example.com
|
||||
KEYCLOAK_REALM=master
|
||||
```
|
||||
|
||||
The auth package will derive `KEYCLOAK_ISSUER` from those two values.
|
||||
|
||||
## WorkOS setup
|
||||
|
||||
1. In WorkOS, create or select the application that will back Mosaic login.
|
||||
2. Configure an AuthKit domain or custom authentication domain for the application.
|
||||
3. Add the redirect URI:
|
||||
|
||||
```text
|
||||
{BETTER_AUTH_URL}/api/auth/oauth2/callback/workos
|
||||
```
|
||||
|
||||
4. Copy the application's `client_id` and `client_secret` into `WORKOS_CLIENT_ID` and `WORKOS_CLIENT_SECRET`.
|
||||
5. Set `WORKOS_ISSUER` to the AuthKit domain from step 2.
|
||||
6. Create the WorkOS organization and attach the enterprise SSO connection you want Mosaic to use.
|
||||
7. Set `NEXT_PUBLIC_WORKOS_ENABLED=true` in the web deployment so the login button is rendered.
|
||||
|
||||
## Keycloak setup
|
||||
|
||||
1. Start from an existing Keycloak realm or create a dedicated realm for Mosaic.
|
||||
2. Create a confidential OIDC client named `mosaic` or your preferred client ID.
|
||||
3. Set the valid redirect URI to:
|
||||
|
||||
```text
|
||||
{BETTER_AUTH_URL}/api/auth/oauth2/callback/keycloak
|
||||
```
|
||||
|
||||
4. Set the web origin to the public Mosaic web URL.
|
||||
5. Copy the client secret into `KEYCLOAK_CLIENT_SECRET`.
|
||||
6. Set either `KEYCLOAK_ISSUER` directly or `KEYCLOAK_URL` + `KEYCLOAK_REALM`.
|
||||
7. Set `NEXT_PUBLIC_KEYCLOAK_ENABLED=true` in the web deployment so the login button is rendered.
|
||||
|
||||
### Local Keycloak smoke test
|
||||
|
||||
If you want to test locally with Docker:
|
||||
|
||||
```bash
|
||||
docker run --rm --name mosaic-keycloak \
|
||||
-p 8080:8080 \
|
||||
-e KEYCLOAK_ADMIN=admin \
|
||||
-e KEYCLOAK_ADMIN_PASSWORD=admin \
|
||||
quay.io/keycloak/keycloak:26.1 start-dev
|
||||
```
|
||||
|
||||
Then configure:
|
||||
|
||||
```bash
|
||||
KEYCLOAK_ISSUER=http://localhost:8080/realms/master
|
||||
KEYCLOAK_CLIENT_ID=mosaic
|
||||
KEYCLOAK_CLIENT_SECRET=...
|
||||
NEXT_PUBLIC_KEYCLOAK_ENABLED=true
|
||||
```
|
||||
|
||||
## Web flow
|
||||
|
||||
The web login page renders provider buttons from `NEXT_PUBLIC_*_ENABLED` flags. Each button links to `/auth/provider/{providerId}`, and that page initiates Better Auth's `signIn.oauth2` flow before handing off to the provider.
|
||||
|
||||
## Failure mode
|
||||
|
||||
Provider config is optional, but partial config is rejected at startup. If any provider-specific env var is present without the full required set, `@mosaicstack/auth` throws a bootstrap error with the missing keys instead of silently registering a broken provider.
|
||||
@@ -1,49 +0,0 @@
|
||||
# User Guide
|
||||
|
||||
> **Status:** Partially migrated. The quickstart, web-dashboard reference, and Discord conversation workflow are current.
|
||||
|
||||
This book is the canonical home for end-user workflows, user-visible behavior, product concepts, and user troubleshooting. Keep installation, deployment, security controls, and recovery procedures in [`ADMIN-GUIDE/`](../ADMIN-GUIDE/); keep implementation detail in [`DEVELOPER-GUIDE/`](../DEVELOPER-GUIDE/).
|
||||
|
||||
## Start here
|
||||
|
||||
- [Documentation atlas](../README.md) — placement rules and source-of-truth boundaries.
|
||||
- [Documentation sitemap](../SITEMAP.md) — resolvable current navigation and authority-gated migration summary.
|
||||
- [Quickstart](getting-started/quickstart.md) — install Mosaic, complete setup, and launch a session.
|
||||
- [Web dashboard](product/web-dashboard.md) — current routes, navigation, chat persistence, projects/tasks views, settings, and admin behavior.
|
||||
- [Discord conversations](workflows/discord-conversations.md) — current authorized parent-channel, thread, attachment, and control workflow.
|
||||
|
||||
## Chapter map
|
||||
|
||||
| Chapter | Scope | Status |
|
||||
| ------------------ | ------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| `getting-started/` | First-use setup, orientation, and quickstarts. | Quickstart is current; additional pages are planned. |
|
||||
| `concepts/` | User-facing terminology, product concepts, and mental models. | Scaffold only. |
|
||||
| `workflows/` | Task-oriented procedures for using Mosaic Stack. | Discord conversation workflow is current. |
|
||||
| `product/` | Current product surfaces and visible behavior. | Web dashboard reference is current. |
|
||||
| `troubleshooting/` | User-visible failures, diagnostics, and fixes. | Scaffold only. |
|
||||
|
||||
### Current pages
|
||||
|
||||
- [Quickstart](getting-started/quickstart.md) — the verified installed-CLI first-use path.
|
||||
- [Web dashboard](product/web-dashboard.md) — verified current Next.js dashboard behavior and limitations.
|
||||
- [Discord conversations](workflows/discord-conversations.md) — verified current Discord user workflow.
|
||||
|
||||
Every promoted page must be added to this index and to [`SITEMAP.md`](../SITEMAP.md) in the same migration slice.
|
||||
|
||||
## Migration backlog — not current navigation
|
||||
|
||||
These are source candidates, not current user guidance:
|
||||
|
||||
- `_old_structure/guides/user-guide.md` — quarantined historical source; verify every claim before promotion. See the [documentation catalog](../reports/documentation/2026-08-10-docs-catalog-audit.md) for its disposition.
|
||||
- The former root `QUICKSTART.md` was an empty placeholder and has been replaced by the current page above.
|
||||
|
||||
Do not link to the quarantine as a current user path. Create a new page only after classifying its audience, status, and evidence in the migration report.
|
||||
|
||||
## Authoring boundary
|
||||
|
||||
New user-facing documentation belongs under one of the chapter directories above. Use a lowercase kebab-case page name, state whether commands are current or held, and link back to this index plus related canonical sources.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[PRD|Product requirements]]
|
||||
@@ -1,129 +0,0 @@
|
||||
---
|
||||
title: Mosaic Stack Quickstart
|
||||
type: guide
|
||||
audience: user
|
||||
status: current
|
||||
source_of_truth: false
|
||||
---
|
||||
|
||||
# Mosaic Stack Quickstart
|
||||
|
||||
Verify and install the versioned Mosaic CLI package, complete first-run setup, connect to a gateway, and launch an agent session. This page covers the installed-CLI path with the default local storage tier.
|
||||
|
||||
> **Scope:** This is an end-user installation route. It does not authorize PostgreSQL setup, production deployment, or starting Gateway/Web directly from a source checkout. Use the [administrator guide](../../ADMIN-GUIDE/README.md) for deployment and the [developer guide](../../DEVELOPER-GUIDE/README.md) for contributor setup.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js 20 or newer.
|
||||
- npm, for the global Mosaic CLI installation.
|
||||
- At least one supported agent runtime:
|
||||
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code)
|
||||
- [Codex](https://github.com/openai/codex)
|
||||
- [OpenCode](https://opencode.ai)
|
||||
- [Pi](https://pi.dev)
|
||||
- Credentials for the runtime or model provider you plan to use.
|
||||
|
||||
## 1. Install Mosaic
|
||||
|
||||
> **Installation hold:** Do not execute the website installer or a script fetched from a mutable repository branch. The current release tooling does not publish an independently verified immutable dependency closure or a signed installer. If your policy requires either property, stop until a release provides it.
|
||||
|
||||
The currently published CLI/framework package is `@mosaicstack/[email protected]`. Pin the exact package version and verify its published artifact integrity before installation:
|
||||
|
||||
```bash
|
||||
registry='https://git.mosaicstack.dev/api/packages/mosaicstack/npm/'
|
||||
package='@mosaicstack/mosaic@0.0.49'
|
||||
expected_integrity='sha512-/Zsjdf8Ln2QchQTG9lirpqSxhDbNyBjOvGkWrDWRugxCuqUWP5V0rUNVDivmPvro+Vyq3hxDyA9i4hDfkEFmMg=='
|
||||
actual_integrity="$(npm view --registry="$registry" "$package" dist.integrity)"
|
||||
test "$actual_integrity" = "$expected_integrity"
|
||||
npm install --global --registry="$registry" "$package"
|
||||
```
|
||||
|
||||
The explicit comparison pins the reviewed top-level package artifact; npm also checks the downloaded tarball against registry integrity metadata. It does **not** make the package's transitive dependency graph independently immutable. Review the [package release](https://git.mosaicstack.dev/mosaicstack/-/packages/npm/%40mosaicstack%2Fmosaic/0.0.49) before proceeding, and stop if the integrity comparison fails.
|
||||
|
||||
The versioned package includes the Mosaic framework and CLI. npm installs it under your configured global prefix. Ensure that prefix's `bin` directory is on `PATH` if your shell cannot find `mosaic`.
|
||||
|
||||
## 2. Complete first-run setup
|
||||
|
||||
The versioned package install does not launch the wizard. Run it manually:
|
||||
|
||||
```bash
|
||||
mosaic wizard
|
||||
```
|
||||
|
||||
The wizard guides framework setup and gateway installation. It can collect your agent identity, preferences, provider configuration, and gateway administrator details interactively.
|
||||
|
||||
For a separately installed or existing gateway, skip local gateway installation and use its URL in the login step below.
|
||||
|
||||
## 3. Verify and sign in
|
||||
|
||||
For a gateway installed on this machine, check its health and setup state:
|
||||
|
||||
```bash
|
||||
mosaic gateway status
|
||||
mosaic gateway verify
|
||||
```
|
||||
|
||||
Sign in without putting your password in shell history or process listings:
|
||||
|
||||
```bash
|
||||
mosaic gateway login
|
||||
```
|
||||
|
||||
The command prompts for the gateway URL, email, and password as needed. Do not pass passwords with `--password`.
|
||||
|
||||
For a remote gateway, provide its URL explicitly:
|
||||
|
||||
```bash
|
||||
mosaic gateway login --gateway https://gateway.example.com
|
||||
```
|
||||
|
||||
## 4. Launch Mosaic
|
||||
|
||||
Open the interactive terminal interface:
|
||||
|
||||
```bash
|
||||
mosaic tui
|
||||
```
|
||||
|
||||
The TUI defaults to `http://localhost:14242` and can prompt for login if no valid session is saved. To connect it to another gateway:
|
||||
|
||||
```bash
|
||||
mosaic tui --gateway https://gateway.example.com
|
||||
```
|
||||
|
||||
You can also launch a supported runtime through Mosaic:
|
||||
|
||||
```bash
|
||||
mosaic pi
|
||||
mosaic claude
|
||||
mosaic codex
|
||||
mosaic opencode
|
||||
```
|
||||
|
||||
Use the launcher matching the runtime you installed and authenticated.
|
||||
|
||||
## 5. Inspect configuration and health
|
||||
|
||||
These commands are safe diagnostics and do not change the product requirements or active task ledger:
|
||||
|
||||
```bash
|
||||
mosaic config show
|
||||
mosaic doctor
|
||||
mosaic gateway logs
|
||||
```
|
||||
|
||||
If the gateway is unhealthy, run `mosaic gateway status` and `mosaic gateway logs` before attempting a reinstall. If your session expires, run `mosaic gateway login` again.
|
||||
|
||||
## Storage and deployment boundary
|
||||
|
||||
The default local gateway tier uses embedded PGlite and does not require an external PostgreSQL or Valkey service. This quickstart intentionally does not configure `DATABASE_URL`, PostgreSQL, pgvector, or a federated deployment.
|
||||
|
||||
For standalone or federated storage, deployment topology, secrets, SSO, backups, or recovery, stop here and use the [administrator guide](../../ADMIN-GUIDE/README.md). For work from a repository checkout, keep `DATABASE_URL` unset and follow the [developer guide](../../DEVELOPER-GUIDE/README.md); do not use root `pnpm dev` as a local PGlite route while the current dotenv safety hold remains active.
|
||||
|
||||
## Related
|
||||
|
||||
- [User Guide](../README.md)
|
||||
- [Documentation atlas](../../README.md)
|
||||
- [Administrator Guide](../../ADMIN-GUIDE/README.md)
|
||||
- [Developer Guide](../../DEVELOPER-GUIDE/README.md)
|
||||
- [Repository README](../../../README.md)
|
||||
@@ -1,276 +0,0 @@
|
||||
---
|
||||
title: Mosaic web dashboard
|
||||
type: guide
|
||||
audience: user
|
||||
status: current
|
||||
source_of_truth: false
|
||||
---
|
||||
|
||||
# Mosaic Web Dashboard
|
||||
|
||||
This page documents the current Next.js dashboard: its routes, navigation, visible
|
||||
views, and the chat persistence behavior supported by the checked-in web and gateway
|
||||
implementation.
|
||||
|
||||
> **Current UI boundary:** Projects and tasks can be displayed in the dashboard, but
|
||||
> the current dashboard does not provide **New Project** or **New Task** controls.
|
||||
> Those entities can be created through authenticated gateway API clients; that API
|
||||
> surface is separate from the views described here.
|
||||
|
||||
## Access and routes
|
||||
|
||||
The dashboard uses the gateway session. Dashboard routes are protected by the web
|
||||
`AuthGuard`; the admin route also requires the `admin` role.
|
||||
|
||||
| Path | Access | Current behavior |
|
||||
| --------------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/` | Any | Redirects to `/chat`. A signed-out visitor is then redirected to `/login`. |
|
||||
| `/login` | Signed out | Email/password sign-in, plus buttons for configured SSO providers. Successful sign-in returns to `/chat`. |
|
||||
| `/register` | Signed out | Creates an account with name, email, and password, then returns to `/chat`. |
|
||||
| `/auth/provider/[provider]` | SSO handoff | Looks up the requested provider and starts an OIDC sign-in when that provider is configured and supports OIDC. Unknown, disabled, or incompatible providers show an error and a link back to login. |
|
||||
| `/chat` | Signed in | Conversation list and streamed assistant chat. |
|
||||
| `/projects` | Signed in | Project cards and the Active Mission status section. |
|
||||
| `/projects/[id]` | Signed in | Project detail view with overview, tasks, missions, and an optional read-only PRD tab. |
|
||||
| `/tasks` | Signed in | Task data in Kanban or list view. |
|
||||
| `/settings` | Signed in | Profile, appearance, notifications, and provider tabs. |
|
||||
| `/admin` | Signed-in admin | User Management and System Health tabs. Non-admin users are redirected away from the admin page. |
|
||||
|
||||
Settings and admin tabs are client-side tabs; changing a tab does not change the URL.
|
||||
|
||||
## Dashboard navigation
|
||||
|
||||
The **Workspace** sidebar contains these links, in order:
|
||||
|
||||
1. **Chat** — `/chat`
|
||||
2. **Tasks** — `/tasks`
|
||||
3. **Projects** — `/projects`
|
||||
4. **Settings** — `/settings`
|
||||
5. **Admin** — `/admin`
|
||||
|
||||
The active link is highlighted, including the parent link when viewing a project
|
||||
such as `/projects/<id>`. The Admin link is rendered in the shared sidebar, but the
|
||||
page itself is still restricted to administrators.
|
||||
|
||||
The top bar provides:
|
||||
|
||||
- a sidebar toggle (collapse/expand on desktop; open/close an overlay on mobile),
|
||||
- the light/dark theme toggle,
|
||||
- the signed-in user's name, and
|
||||
- **Sign out**, which returns to `/login`.
|
||||
|
||||
The applied global theme is stored in browser local storage under `mosaic-theme`.
|
||||
|
||||
## Chat
|
||||
|
||||
### Starting and managing conversations
|
||||
|
||||
Open `/chat` and either select a conversation or choose **Start new conversation**
|
||||
in the empty state. The conversation sidebar also has **New conversation**. Creating
|
||||
one calls the gateway and gives the conversation a server-side ID before the first
|
||||
message is sent.
|
||||
|
||||
The sidebar currently supports:
|
||||
|
||||
- searching conversation titles,
|
||||
- selecting a conversation,
|
||||
- renaming a conversation inline (Enter or leaving the field commits the new title),
|
||||
- deleting a conversation after confirmation, and
|
||||
- grouping conversations by project when project data is available.
|
||||
|
||||
Archived conversations are filtered out of the sidebar. The current dashboard does
|
||||
not expose archive/restore controls.
|
||||
|
||||
If no conversation is selected when a message is sent, the dashboard creates one
|
||||
automatically. A new conversation is titled from the first 60 characters of the
|
||||
first message; an empty placeholder conversation is similarly retitled after its
|
||||
first message. The active conversation is held in page state, not in the URL: the
|
||||
route remains `/chat` rather than changing to `/chat/<id>`. After a refresh, select
|
||||
the stored conversation again from the sidebar.
|
||||
|
||||
### Sending and streaming
|
||||
|
||||
The chat composer provides:
|
||||
|
||||
- a model selector populated from available gateway providers and models,
|
||||
- a multiline message field,
|
||||
- character and approximate token counts, and
|
||||
- a **Send** button.
|
||||
|
||||
Use **Cmd/Ctrl+Enter** to send. The composer is disabled while a response is
|
||||
streaming. The interface displays a **Stop** control during streaming, but the
|
||||
current `ChatPage` does not pass a stop handler, so cancellation is not a reliable
|
||||
current dashboard action.
|
||||
|
||||
Assistant and user messages render Markdown. Assistant messages can show model and
|
||||
token metadata when it is present in the returned message, and rendered user/assistant
|
||||
messages have a copy control.
|
||||
|
||||
### What is persisted
|
||||
|
||||
Assistant replies are not page-only or memory-only. The current flow is:
|
||||
|
||||
1. The browser creates or selects a conversation and optimistically displays the
|
||||
user's message.
|
||||
2. The browser submits the user message to the gateway conversation-message API and
|
||||
sends the turn over the authenticated `/chat` WebSocket namespace.
|
||||
3. The gateway streams the assistant response to the page. At `agent_end`, it saves
|
||||
non-empty assistant text to the conversation with model, provider, tool-call, and
|
||||
token-usage metadata when available.
|
||||
4. Selecting the conversation later loads `/api/conversations/<id>/messages`, so
|
||||
stored user and assistant messages are shown again. When the gateway has to create
|
||||
or resume the agent session for that conversation, it also loads stored conversation
|
||||
history as context.
|
||||
|
||||
The live page appends the completed response as soon as the stream ends; the gateway
|
||||
persistence write is asynchronous. Therefore a persistence error can leave a reply
|
||||
visible in the current page while it is unavailable after a later reload. The gateway
|
||||
redacts sensitive content before emitting and storing assistant text.
|
||||
|
||||
## Projects and missions
|
||||
|
||||
### Project list: `/projects`
|
||||
|
||||
The project page loads the signed-in user's projects and shows either:
|
||||
|
||||
- project cards with name, status, description, and creation date, or
|
||||
- **No projects yet** with the message that projects appear when created through the
|
||||
gateway API.
|
||||
|
||||
The page also shows **Active Mission**. It reports the mission ID, phase, task
|
||||
completion count, and status when coordination data is available; otherwise it
|
||||
shows **No active mission detected**.
|
||||
|
||||
There is no New Project button or project form on this page. The gateway has
|
||||
project CRUD endpoints, but this dashboard page currently reads project data only.
|
||||
|
||||
### Project detail: `/projects/<id>`
|
||||
|
||||
A project detail page shows its name, status, description, created/updated dates,
|
||||
and task summary counts for total, done, in progress, and blocked tasks. Its tabs
|
||||
are:
|
||||
|
||||
- **Overview** — up to five recently updated tasks, a mission summary, and non-empty
|
||||
project metadata.
|
||||
- **Tasks (`n`)** — task status filters and clickable task rows.
|
||||
- **Missions (`n`)** — a status-ordered mission timeline.
|
||||
- **PRD** — present only when project metadata contains non-empty `prd` or
|
||||
`prdContent` text; the content is displayed read-only.
|
||||
|
||||
Selecting a task from the project detail Tasks tab opens a detail dialog with its
|
||||
status, priority, description, assignee, due date, timestamps, tags, pull-request
|
||||
links, and notes when those fields exist. The dialog can be closed with its close
|
||||
button, the backdrop, or Escape. The dashboard does not provide project or task
|
||||
edit controls in this view.
|
||||
|
||||
## Tasks
|
||||
|
||||
Open `/tasks` to load the tasks visible to the signed-in user. The default view is
|
||||
**Kanban**; a toggle switches to **List**.
|
||||
|
||||
- Kanban columns are **Not Started**, **In Progress**, **Blocked**, and **Done**.
|
||||
- Kanban cards show title, priority, optional description, status, and due date.
|
||||
- List view shows title, status, priority, and due date.
|
||||
- The supported task status set also includes `cancelled`; it is not a Kanban
|
||||
column, but a returned cancelled task can appear in List view.
|
||||
|
||||
The top-level Tasks page has no New Task button, form, or working task edit dialog.
|
||||
Clicking a task in that page does not open the project-detail dialog. The gateway
|
||||
supports authenticated task CRUD separately, while this dashboard page currently
|
||||
reads and presents task data.
|
||||
|
||||
## Settings
|
||||
|
||||
Open `/settings`. The page has four tabs and opens on **Profile**.
|
||||
|
||||
### Profile
|
||||
|
||||
- **Display Name** can be edited.
|
||||
- **Email** is displayed but disabled; the page says it cannot be changed there.
|
||||
- **Avatar URL** can be edited.
|
||||
- **Save changes** sends the profile update through BetterAuth and reports saving,
|
||||
saved, or an error state.
|
||||
|
||||
### Appearance
|
||||
|
||||
The tab presents **System**, **Light**, and **Dark** theme choices, a **Collapse
|
||||
sidebar by default** switch, and a **Default Model** text field. **Save changes**
|
||||
saves these as user preferences.
|
||||
|
||||
Current implementation limits are worth noting: the shared sidebar provider starts
|
||||
expanded and does not read `ui.sidebar_collapsed` on page load; the global applied
|
||||
theme is controlled by the top-bar theme toggle; and the chat page initially selects
|
||||
the first available provider model rather than reading `ui.default_model` itself.
|
||||
Do not treat these preference fields as proof that those defaults are applied across
|
||||
all dashboard sessions.
|
||||
|
||||
### Notifications
|
||||
|
||||
The tab presents and saves three email preferences:
|
||||
|
||||
- **Agent task completed** — initially off,
|
||||
- **Mentions** — initially on, and
|
||||
- **Weekly digest** — initially off.
|
||||
|
||||
### Providers
|
||||
|
||||
The Providers tab contains SSO discovery and LLM provider discovery/testing areas:
|
||||
|
||||
- **SSO Providers** shows configured providers and their protocols, callback path,
|
||||
team-sync claim, SAML fallback, and warnings when supplied by the gateway. It does
|
||||
not configure SSO from the dashboard.
|
||||
- **LLM Providers** shows configured providers as Active or Inactive. A provider can
|
||||
be tested for reachability; the result may include latency, an error, and the
|
||||
number of discovered models. Expanding a provider shows model capabilities,
|
||||
context size, cost, and the default-model marker.
|
||||
|
||||
When no LLM providers are configured, the page displays setup guidance mentioning
|
||||
`OLLAMA_BASE_URL` and `MOSAIC_CUSTOM_PROVIDERS`. Provider credentials and provider
|
||||
configuration are not editable in this dashboard tab.
|
||||
|
||||
## Admin panel
|
||||
|
||||
The `/admin` page is wrapped in an admin-role guard. It opens on **User Management**
|
||||
and provides **System Health** as the second tab.
|
||||
|
||||
### User Management
|
||||
|
||||
The page loads the user list and provides:
|
||||
|
||||
- a user count,
|
||||
- **+ New User**, with name, email, password, and `member`/`admin` role fields,
|
||||
- role promotion/demotion,
|
||||
- ban/unban,
|
||||
- deletion after confirmation, and
|
||||
- a retry action when loading fails.
|
||||
|
||||
The table shows name/email, role, active or banned status, creation date, and
|
||||
available actions.
|
||||
|
||||
### System Health
|
||||
|
||||
The health tab loads the gateway's overall `ok` or `degraded` status and provides a
|
||||
**Refresh** action. Its cards cover:
|
||||
|
||||
- PostgreSQL database status and latency/error,
|
||||
- Valkey cache status and latency/error,
|
||||
- active agent-session count, and
|
||||
- configured LLM providers and model counts.
|
||||
|
||||
## Evidence used for this page
|
||||
|
||||
The behavior above was checked against the current implementation and focused tests,
|
||||
not copied forward as-is from the historical mixed guide. The main evidence files
|
||||
are:
|
||||
|
||||
- `apps/web/src/app/(dashboard)/` route pages and `apps/web/src/app/page.tsx`,
|
||||
- `apps/web/src/components/layout/`, `apps/web/src/components/chat/`,
|
||||
`apps/web/src/components/projects/`, and `apps/web/src/components/tasks/`,
|
||||
- `apps/web/e2e/navigation.spec.ts`, `chat.spec.ts`, `projects.spec.ts`,
|
||||
`settings.spec.ts`, and `admin.spec.ts`,
|
||||
- `apps/gateway/src/chat/chat.gateway.ts` and
|
||||
`apps/gateway/src/__tests__/conversation-persistence.test.ts`,
|
||||
- `apps/gateway/src/chat/chat.gateway-redaction.spec.ts`, and
|
||||
- the authenticated gateway controllers under `apps/gateway/src/conversations/`,
|
||||
`projects/`, `tasks/`, and `admin/`.
|
||||
|
||||
Related: [User Guide index](../README.md) and [SSO provider runbook](../../ADMIN-GUIDE/security/sso-providers.md).
|
||||
@@ -1,128 +0,0 @@
|
||||
# Discord conversations
|
||||
|
||||
> **Status:** Current Discord workflow for an administrator-provisioned, authorized guild channel.
|
||||
>
|
||||
> Telegram shared-contract parity, Matrix channel conversations, and a gateway-wide shared adapter registry are not current features. See [Current versus planned](#current-versus-planned) before using any older channel instructions.
|
||||
>
|
||||
> **Audience:** People conversing with an agent through Discord.
|
||||
|
||||
This workflow assumes an administrator has configured the Discord bot, gateway connection, allowlists, and a logical-agent binding. Users cannot create a binding or authorize themselves from Discord.
|
||||
|
||||
## Current versus planned
|
||||
|
||||
| Surface | Status | What you can rely on |
|
||||
| ----------------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Discord guild messages | **Current live routing** | Authorized messages route to the configured logical agent; parent/thread delivery is tested, but ordinary durable history is not guaranteed. |
|
||||
| Telegram | **Not shared-contract parity** | A raw legacy plugin exists, but its current source has no equivalent documented authorization, pairing, route, or focused package tests. |
|
||||
| Matrix | **Not implemented as a channel workflow** | No current gateway channel adapter and test boundary establishes a Matrix conversation workflow. |
|
||||
| Shared channel registry | **Not implemented** | The gateway's current registry hosts lifecycle wrappers; it does not provide universal channel routing or health. |
|
||||
|
||||
## Start in a configured parent channel
|
||||
|
||||
Send a normal message in the administrator-configured parent text channel. You do **not** need to mention the bot for an ordinary turn.
|
||||
|
||||
For an authorized user, Mosaic:
|
||||
|
||||
1. checks the guild, parent channel, user allowlist, pairing, role, and rate limit;
|
||||
2. keeps the response target in the parent channel; and
|
||||
3. routes the turn to the binding's logical agent using a stable conversation address.
|
||||
|
||||
No Discord thread is created for this untagged parent-channel case. The response is sent back to that same channel.
|
||||
|
||||
Messages from an unconfigured guild/channel, an unallowlisted user, an unpaired user, or a user without a role that can send are ignored without creating a thread or dispatching to the gateway. Bot-authored messages are ignored. Direct messages are not handled by the current guild ingress path.
|
||||
|
||||
## Start a threaded topic with a mention
|
||||
|
||||
Mention the bot in a parent channel when you want a separate topic:
|
||||
|
||||
```text
|
||||
@Mosaic investigate the deployment failure
|
||||
```
|
||||
|
||||
The current Discord adapter creates a public thread for the message, removes the bot mention from the content sent to the agent, and targets the response to that thread. If the message already has a Discord thread attached, the adapter reuses it instead of creating another one.
|
||||
|
||||
Authorization happens before thread creation. If the user, guild, parent channel, pairing, role, or rate check fails, no thread is created. If Discord cannot create or fetch the requested thread, the message is not dispatched because Mosaic cannot guarantee the requested response destination.
|
||||
|
||||
## Continue inside a thread
|
||||
|
||||
Reply in the existing authorized thread without mentioning the bot again. The adapter:
|
||||
|
||||
- authorizes the message against the configured parent text channel;
|
||||
- keeps the thread as the response target; and
|
||||
- never attempts to create a nested thread.
|
||||
|
||||
A category above the text channel is not used as the authorization parent. Only the actual configured text-channel parent grants thread inheritance.
|
||||
|
||||
The stable conversation address is formed from the configured logical agent, channel name, and response channel/thread, for example:
|
||||
|
||||
```text
|
||||
<logical-agent-id>:discord:<response-channel-id>
|
||||
```
|
||||
|
||||
It does not contain Claude, Codex, Pi, OpenCode, a model, a provider, a process, or a native runtime-session ID. The gateway owns runtime selection behind that route, so changing the runtime/provider does not require a new Discord address.
|
||||
|
||||
### Durability limitation
|
||||
|
||||
Treat the current Discord path as **live routing and delivery**, not guaranteed durable conversation history. The Discord conversation address above is an external route string, while persisted conversation/message rows use UUID conversation IDs. No current external-route-to-UUID mapping was found. The gateway can continue dispatching after a persistence/binding failure, so a reply may appear in Discord without durable history or restart/resume continuity.
|
||||
|
||||
Do not rely on Discord as the sole record of a conversation. Durable history requires an implementation that maps the external route to a UUID, surfaces persistence failure, and proves fresh-message persistence and restart recovery in an integration test.
|
||||
|
||||
## Attachments
|
||||
|
||||
An authorized message may contain text, attachments, or an attachment without text. The current adapter maps attachments into the shared message shape and preserves the native attachment ID, name, URL, content type, and optional size.
|
||||
|
||||
The gateway accepts only bounded attachment metadata: at most 10 attachments, HTTPS URLs without credentials, query strings, or fragments, and bounded ID, name, URL, MIME-type, size, and total metadata values. An unsafe or malformed attachment is rejected before the message is acknowledged or dispatched. Binary content is not embedded in the gateway message; the attachment remains a validated external reference.
|
||||
|
||||
## Runtime controls
|
||||
|
||||
The current Discord text controls are:
|
||||
|
||||
```text
|
||||
/approve
|
||||
/stop <approval>
|
||||
```
|
||||
|
||||
They remain on the current parent/thread route and do not create a new topic. Approval and stop require an already enrolled durable session; ordinary Discord chat does not prove that enrollment occurred. These are privileged operations: the paired user must have the `admin` role and a provisioned `mosaicUserId`, the gateway must have a tenant configured for the control path, and the enrolled durable session must still belong to the bound logical agent. A stop must present the exact approval reference created for that target; approval consumption is one-time.
|
||||
|
||||
If these checks fail, the control operation is denied or produces no successful control result. Do not assume that being able to read a channel grants control authority.
|
||||
|
||||
## Response and delivery behavior
|
||||
|
||||
The gateway emits raw stream events to the current Discord compatibility path. The plugin buffers `agent:start`/`agent:text` output and sends the completed response on `agent:end`; this is not a claim of token-by-token Discord rendering.
|
||||
|
||||
Outbound Discord text is split at a 1,900-character boundary. Transient rate-limit, server, and network failures are retried up to three attempts with one deterministic nonce per correlation/chunk; permanent delivery failures are not retried. A response route is checked against the configured logical-agent/channel binding before Discord is contacted.
|
||||
|
||||
## If a message gets no response
|
||||
|
||||
Check these possibilities with the administrator:
|
||||
|
||||
1. You are in a direct message, an unconfigured guild/channel, or a thread whose parent is not configured.
|
||||
2. Your Discord user ID is missing from the user allowlist or `pairedUsers`.
|
||||
3. Your pairing is `viewer`, which cannot send ordinary agent turns.
|
||||
4. The per-user/channel message or mention-thread limit was reached.
|
||||
5. The bot is not connected to Discord or the gateway Socket.IO `/chat` namespace.
|
||||
6. A mentioned topic could not create/fetch its thread.
|
||||
7. The gateway rejected the signed envelope, route, attachment, or replayed native message ID.
|
||||
8. `/approve` or `/stop <approval>` was attempted without the required admin pairing, tenant, pre-enrolled durable session, or exact approval.
|
||||
|
||||
These failures are intentionally fail-closed; an unauthorized or unverifiable message should not create a thread or agent side effect.
|
||||
|
||||
## Not current: Telegram and Matrix
|
||||
|
||||
Do not substitute Telegram or Matrix instructions for this workflow:
|
||||
|
||||
- The current Telegram plugin uses raw Telegraf and Socket.IO messages, maps a chat to `telegram-<chatId>`, accepts text only, and does not establish the Discord-style service-token, allowlist, pairing, shared-route, or attachment boundary.
|
||||
- No current Matrix gateway channel adapter, channel binding, user authorization flow, or focused channel tests establish a Matrix conversation workflow.
|
||||
- The current gateway plugin list is lifecycle-only; it is not proof that every channel shares this Discord behavior.
|
||||
|
||||
Those are parity/design gaps, not alternate user workflows.
|
||||
|
||||
## Evidence and related pages
|
||||
|
||||
- [Channel protocol architecture](../../DEVELOPER-GUIDE/architecture/channel-protocol.md) — current shared types, Discord compatibility path, and explicit parity boundary.
|
||||
- [Discord ingress security](../../ADMIN-GUIDE/security/discord-ingress.md) — administrator configuration, authentication, authorization, and failure controls.
|
||||
- [`plugins/discord/src/index.ts`](../../../plugins/discord/src/index.ts) — native Discord routing and delivery implementation.
|
||||
- [`plugins/discord/src/index.test.ts`](../../../plugins/discord/src/index.test.ts) — parent, mention, existing-thread, authorization, attachment, rate, egress, and health tests.
|
||||
- [`apps/gateway/src/plugin/discord-ingress.security.spec.ts`](../../../apps/gateway/src/plugin/discord-ingress.security.spec.ts) — gateway signature, replay, binding, attachment, approval, and stop tests.
|
||||
- [`apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts`](../../../apps/gateway/src/__tests__/integration/tess-cross-surface.integration.test.ts) — Discord control-flow test with explicit durable-session pre-enrollment; it is not fresh-message persistence evidence.
|
||||
- [User Guide](../README.md)
|
||||
@@ -0,0 +1,151 @@
|
||||
# ADR: Optional AI egress gateways for runtime-neutral Mos
|
||||
|
||||
**Status:** Proposed for controlled prototypes; not approved as Mosaic core
|
||||
|
||||
**Date:** 2026-07-14
|
||||
|
||||
**Issues:** #754, #755
|
||||
|
||||
**Decision owner:** Mosaic Gateway / provider-adapter architecture
|
||||
|
||||
## Context
|
||||
|
||||
The emergency Mos continuity path kept Claude Code as the harness and translated Anthropic Messages traffic to Codex OAuth through a small localhost proxy. That preserved the existing Claude Discord plugin and transcript, but exposed two architectural facts:
|
||||
|
||||
1. Harness identity, channel entitlement, provider credentials, and inference transport are separate concerns.
|
||||
2. A generic AI gateway can improve provider routing, budgets, and observability, but must not become Mosaic's identity, authorization, tenant, or orchestration boundary.
|
||||
|
||||
The Tess qualification report also found that current provider rebinding is not identity-continuous failover. Mosaic still needs a logical agent identity, durable connector lease/fencing, canonical handoff/checkpoint, exactly-once receipts, concrete harness adapters, and cross-harness rollback E2E.
|
||||
|
||||
## Decision
|
||||
|
||||
Mosaic MAY support LiteLLM, Bifrost, the purpose-built Claude/Codex proxy, or future gateways as optional egress implementations behind `IProviderAdapter` / `AgentRuntimeProvider`.
|
||||
|
||||
Mosaic Gateway remains authoritative for:
|
||||
|
||||
- authenticated actor and tenant identity;
|
||||
- logical agent identity and connector binding;
|
||||
- authorization, approval, and policy;
|
||||
- lease epoch and stale-holder fencing;
|
||||
- audit correlation and redaction;
|
||||
- canonical handoff/checkpoint state;
|
||||
- idempotency and side-effect receipts.
|
||||
|
||||
An egress gateway MUST NOT:
|
||||
|
||||
- receive channel ingress directly;
|
||||
- authorize tools or connector ownership;
|
||||
- define Mosaic tenant or agent identity;
|
||||
- persist raw Mosaic handoffs or channel credentials;
|
||||
- bypass adapter capability negotiation;
|
||||
- silently fail over when policy, lease, or provider health is uncertain.
|
||||
|
||||
Allowed topology:
|
||||
|
||||
```text
|
||||
Discord / Matrix / CLI / web
|
||||
↓
|
||||
Mosaic Gateway: identity, authz, lease/fence, approvals, audit
|
||||
↓
|
||||
IProviderAdapter / AgentRuntimeProvider
|
||||
↓
|
||||
optional egress gateway
|
||||
↓
|
||||
upstream provider or subscription-backed OAuth session
|
||||
```
|
||||
|
||||
## Candidate assessment
|
||||
|
||||
### Purpose-built `raine/claude-code-proxy`
|
||||
|
||||
**Disposition:** Approved only for the verified emergency localhost bridge.
|
||||
|
||||
Strengths:
|
||||
|
||||
- explicit Codex device OAuth flow;
|
||||
- small operational surface;
|
||||
- Anthropic Messages translation suitable for Claude Code;
|
||||
- model and reasoning-effort enforcement;
|
||||
- straightforward loopback systemd supervision and rollback.
|
||||
|
||||
Constraints:
|
||||
|
||||
- not a Mosaic multi-tenant control plane;
|
||||
- Claude built-in channels still depend on Claude subscription entitlement and feature lookup;
|
||||
- model aliases can obscure the upstream model unless proxy policy/logs are treated as evidence;
|
||||
- no replacement for connector leasing, canonical handoff, or exactly-once effects.
|
||||
|
||||
### LiteLLM
|
||||
|
||||
**Disposition:** Candidate for a formal adapter-only prototype and terms/security review.
|
||||
|
||||
Current documentation states that ChatGPT subscription access is available through an OAuth device-code flow. LiteLLM also provides broad provider routing, virtual keys, budgets, observability, and OpenAI/Anthropic-compatible surfaces.
|
||||
|
||||
Required prototype gates:
|
||||
|
||||
- verify the exact ChatGPT subscription OAuth flow and supported models against current provider terms;
|
||||
- document token location, encryption, revocation, refresh, scope, and incident response;
|
||||
- prove tenant isolation and prevent virtual keys from becoming Mosaic principals;
|
||||
- verify streaming, tool calls, reasoning controls, cancellation, and idempotency metadata;
|
||||
- fail closed instead of selecting an unhealthy provider merely to return a result;
|
||||
- demonstrate that Mosaic audit correlation survives gateway retries/failover;
|
||||
- keep channel ingress and connector credentials outside LiteLLM.
|
||||
|
||||
Source references:
|
||||
|
||||
- [LiteLLM ChatGPT subscription provider](https://docs.litellm.ai/docs/providers/chatgpt)
|
||||
- [LiteLLM providers](https://docs.litellm.ai/docs/providers)
|
||||
|
||||
### Bifrost
|
||||
|
||||
**Disposition:** Candidate for governance/routing research; subscription OAuth compatibility unverified.
|
||||
|
||||
Useful concepts include virtual keys, budgets, rate limits, weighted load balancing, and automatic provider failover. Those features may inform Mosaic egress policy, but Bifrost virtual keys are downstream credentials—not Mosaic actors or tenants.
|
||||
|
||||
Required prototype gates:
|
||||
|
||||
- verify Codex/ChatGPT subscription OAuth rather than assuming API-key compatibility;
|
||||
- map budgets and virtual keys to server-derived Mosaic tenants without duplicating authority;
|
||||
- prove failover does not violate connector lease, approval, or exactly-once semantics;
|
||||
- ensure request/response logs are redacted before persistence;
|
||||
- disable or constrain automatic failover when policy or side-effect state is ambiguous.
|
||||
|
||||
Source references:
|
||||
|
||||
- [Bifrost overview](https://docs.getbifrost.ai/overview)
|
||||
- [Bifrost repository](https://github.com/maximhq/bifrost)
|
||||
|
||||
### `teremterem/claude-code-gpt-5-codex`
|
||||
|
||||
**Disposition:** Not selected as the emergency implementation; useful as a historical LiteLLM recipe.
|
||||
|
||||
The reviewed repository uses `OPENAI_API_KEY`, tells previously authenticated Claude users to log out, and documents a Claude Web Search schema incompatibility. Logging Claude out conflicts with the channel-entitlement requirement observed in the live Mos cutover. The repository therefore does not, as provided, satisfy subscription-OAuth plus built-in-channel continuity.
|
||||
|
||||
Source references:
|
||||
|
||||
- [Repository](https://github.com/teremterem/claude-code-gpt-5-codex)
|
||||
- [Environment template](https://github.com/teremterem/claude-code-gpt-5-codex/blob/main/.env.template)
|
||||
|
||||
## Security consequences
|
||||
|
||||
- Subscription OAuth grants are high-value credentials and require the same lifecycle controls as service credentials.
|
||||
- Downstream virtual keys reduce provider-key exposure but do not establish user, tenant, or agent authority.
|
||||
- Automatic retry/failover can duplicate tool or external side effects unless Mosaic owns operation IDs and receipts.
|
||||
- Gateway telemetry can contain prompts, tool schemas, and model output; redaction and retention policy must apply before persistence.
|
||||
- A localhost unauthenticated translation endpoint must remain loopback-only and process-isolated.
|
||||
|
||||
## Acceptance before production use
|
||||
|
||||
1. Threat model and provider-terms review approved.
|
||||
2. Credential lifecycle and revocation drill documented and exercised.
|
||||
3. Adapter contract tests pass for streaming, tools, cancellation, reasoning policy, errors, and audit correlation.
|
||||
4. Tenant-bound authorization remains entirely in Mosaic Gateway.
|
||||
5. Failure injection proves no duplicate side effects across retries or provider failover.
|
||||
6. Rollback to the prior provider path is exercised.
|
||||
7. Independent code and security reviews approve the exact deployed revision.
|
||||
|
||||
## Follow-up
|
||||
|
||||
- #754 owns cross-harness logical identity, checkpoint, receipt, adapter, and failover work.
|
||||
- #755 / PR #757 implements the first logical identity and connector lease/fencing boundary.
|
||||
- A later issue should prototype LiteLLM and Bifrost behind the provider adapter after #755 is merged and independently qualified.
|
||||
@@ -0,0 +1,751 @@
|
||||
# Channel Protocol Architecture
|
||||
|
||||
**Status:** Official adapter baseline implemented by #756; extended registry/multiplexing remains iterative
|
||||
**Authors:** Mosaic Core Team
|
||||
**Last Updated:** 2026-07-14
|
||||
**Covers:** M7-001 (OfficialChannelAdapter interface), M7-002 (ChannelMessageDto protocol), M7-003 (Matrix integration design), M7-004 (conversation multiplexing), M7-005 (remote auth bridging), M7-006 (agent-to-agent communication via Matrix), M7-007 (multi-user isolation in Matrix)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The channel protocol defines a unified abstraction layer between Mosaic's core messaging infrastructure and the external communication channels it supports (Matrix, Discord, Telegram, TUI, WebUI, and future channels).
|
||||
|
||||
The implemented baseline is exported from `@mosaicstack/types` and consists of four contract groups:
|
||||
|
||||
1. `OfficialChannelAdapter` — transport lifecycle and connection health.
|
||||
2. `ChannelMessageDto` / `ChannelAttachmentDto` — canonical transport data.
|
||||
3. `ChannelConversationRouteDto` — stable logical-agent conversation and authorization address.
|
||||
4. `ChannelResponseTargetDto` — channel/thread destination for replies.
|
||||
|
||||
All channel-specific translation logic lives inside the adapter implementation. Runtime selection does not: gateway durable-session and provider services may rebind the logical session from Claude to Codex, Pi, OpenCode, or another harness without reconnecting the channel adapter.
|
||||
|
||||
---
|
||||
|
||||
## M7-001: OfficialChannelAdapter Interface
|
||||
|
||||
```typescript
|
||||
interface OfficialChannelAdapter {
|
||||
/** Stable, lowercase adapter identifier such as "discord" or "matrix". */
|
||||
readonly name: string;
|
||||
/** Establish both native-channel and gateway connections. */
|
||||
start(): Promise<void>;
|
||||
/** Gracefully close connections and release resources. */
|
||||
stop(): Promise<void>;
|
||||
/** Best-effort health; ordinary disconnection is a result, not an exception. */
|
||||
health(): Promise<{
|
||||
status: 'connected' | 'degraded' | 'disconnected';
|
||||
detail?: string;
|
||||
}>;
|
||||
}
|
||||
```
|
||||
|
||||
The small lifecycle seam lets the gateway host official plugins uniformly without moving native message translation into gateway core. Message ingress remains adapter-owned; gateway policy, durable session routing, auditing, and runtime/provider selection remain gateway-owned.
|
||||
|
||||
### Stable conversation route
|
||||
|
||||
```typescript
|
||||
interface ChannelConversationRouteDto {
|
||||
bindingId: string;
|
||||
logicalAgentId: string;
|
||||
conversationId: string;
|
||||
channelName: string;
|
||||
authorizationChannelId: string;
|
||||
responseTarget: { channelId: string; threadId?: string };
|
||||
}
|
||||
```
|
||||
|
||||
Harness, provider, model, process, and native runtime-session identifiers are forbidden from this route. Runtime adapters consume the gateway's durable logical-session binding; channel adapters consume only the stable route and response target.
|
||||
|
||||
### Typed ingress and egress ports
|
||||
|
||||
`ChannelIngressPort` is the transport-neutral direct-integration seam for official adapters. The current deployed Discord adapter preserves its existing HMAC-signed Socket.IO compatibility ingress so gateway-side service authentication, replay protection, approval handling, and correlation semantics remain unchanged; it normalizes the same `ChannelIngressDto` before signing. The adapter uses a supplied `ChannelIngressPort` directly when a future gateway registration provides one. New adapters must use the shared ports rather than adding channel branches to gateway core.
|
||||
|
||||
`ChannelBindingDto` contains the configuration-owned workspace/channel→logical-agent mapping and paired external principals; credentials are absent. After native allowlist, pairing, and role checks pass, an adapter submits `ChannelIngressDto` to `ChannelIngressPort.receive()`. It includes the normalized message, `ChannelAuthorizedPrincipalDto`, operation, correlation ID, native message ID, and stable route. Unauthorized input never reaches the port.
|
||||
|
||||
Gateway policy and runtime routing produce `ChannelEgressDto`, which `ChannelEgressPort.send()` delivers to the route's response target. Discord's existing HMAC envelope is its authenticated wire encoding of this boundary; future Matrix/Slack adapters use their native authenticated transports while preserving the same actor/operation/correlation semantics.
|
||||
|
||||
### Adapter Registration
|
||||
|
||||
Adapters are registered with the gateway plugin host at startup. The host calls `start()`/`stop()` and may monitor `health()` on a configurable interval. A richer dynamic `ChannelRegistry` remains a compatible future extension of this lifecycle contract.
|
||||
|
||||
```
|
||||
ChannelRegistry
|
||||
└── register(adapter: OfficialChannelAdapter): void
|
||||
└── getAdapter(name: string): OfficialChannelAdapter | null
|
||||
└── listAdapters(): OfficialChannelAdapter[]
|
||||
└── healthAll(): Promise<Record<string, AdapterHealth>>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## M7-002: ChannelMessageDto Protocol
|
||||
|
||||
### Canonical Message Format
|
||||
|
||||
```typescript
|
||||
interface ChannelMessageDto {
|
||||
/**
|
||||
* Globally unique message ID.
|
||||
* Format: UUID v4. Generated by the adapter when receiving, or by Mosaic
|
||||
* when sending. Channel-native IDs are stored in metadata.channelMessageId.
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* Channel-native room/conversation/channel identifier.
|
||||
* The adapter populates this from the inbound message.
|
||||
* For outbound messages, the caller supplies the target channel.
|
||||
*/
|
||||
channelName: string;
|
||||
channelId: string;
|
||||
|
||||
/**
|
||||
* Channel-native identifier of the message sender.
|
||||
* For Mosaic-originated messages this is the Mosaic userId or agentId.
|
||||
*/
|
||||
senderId: string;
|
||||
|
||||
/** Sender classification. */
|
||||
senderKind: 'user' | 'agent' | 'system';
|
||||
|
||||
/**
|
||||
* Textual content of the message.
|
||||
* For non-text content types (image, file) this may be an empty string
|
||||
* or an alt-text description; the actual payload is in `attachments`.
|
||||
*/
|
||||
content: string;
|
||||
|
||||
/**
|
||||
* Hint for how `content` should be interpreted and rendered.
|
||||
* - "text" — plain text, no special rendering
|
||||
* - "markdown" — CommonMark markdown
|
||||
* - "code" — code block (use metadata.language for the language tag)
|
||||
* - "image" — binary image; content is empty, see attachments
|
||||
* - "file" — binary file; content is empty, see attachments
|
||||
*/
|
||||
contentKind: 'text' | 'markdown' | 'code' | 'image' | 'file';
|
||||
|
||||
/**
|
||||
* Arbitrary key-value metadata for channel-specific extension fields.
|
||||
* Examples: { channelMessageId, language, reactionEmoji, channelType }.
|
||||
* Adapters should store channel-native IDs here so round-trip correlation
|
||||
* is possible without altering the canonical fields.
|
||||
*/
|
||||
metadata: Readonly<Record<string, ChannelMetadataValue>>;
|
||||
|
||||
/**
|
||||
* Optional thread or reply-chain identifier.
|
||||
* For threaded channels (Matrix, Discord threads, Telegram topics) this
|
||||
* groups messages into a logical thread scoped to the same channelId.
|
||||
*/
|
||||
threadId?: string;
|
||||
|
||||
/**
|
||||
* The canonical message ID this message is a reply to.
|
||||
* Maps to channel-native reply/quote mechanisms in each adapter.
|
||||
*/
|
||||
replyToId?: string;
|
||||
|
||||
/**
|
||||
* Binary or URI-referenced attachments.
|
||||
* Each attachment carries its MIME type and a URL or base64 payload.
|
||||
*/
|
||||
attachments?: readonly ChannelAttachmentDto[];
|
||||
|
||||
/** ISO-8601 wall-clock timestamp when the message was sent/received. */
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
interface ChannelAttachmentDto {
|
||||
/** Channel-native attachment identifier. */
|
||||
id: string;
|
||||
|
||||
/** Filename or display name. */
|
||||
name: string;
|
||||
|
||||
/** MIME type when supplied by the channel. */
|
||||
mimeType: string | null;
|
||||
|
||||
/**
|
||||
* URL pointing to the attachment, OR a `data:` URI with base64 payload.
|
||||
* Adapters that receive file uploads SHOULD store to object storage and
|
||||
* populate a stable URL here rather than embedding the raw bytes.
|
||||
*/
|
||||
url: string;
|
||||
|
||||
/** Size in bytes, if known. */
|
||||
sizeBytes?: number;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Channel Translation Reference
|
||||
|
||||
The following sections document how each supported channel maps its native message format to and from `ChannelMessageDto`.
|
||||
|
||||
### Matrix
|
||||
|
||||
| ChannelMessageDto field | Matrix equivalent |
|
||||
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `id` | Generated UUID; `metadata.channelMessageId` = Matrix event ID (`$...`) |
|
||||
| `channelId` | Matrix room ID (`!roomid:homeserver`) |
|
||||
| `senderId` | Matrix user ID (`@user:homeserver`) |
|
||||
| `senderKind` | Always `"user"` for inbound; `"agent"` or `"system"` for outbound |
|
||||
| `content` | `event.content.body` |
|
||||
| `contentKind` | `"markdown"` if `msgtype = m.text` and body contains markdown; `"text"` otherwise; `"image"` for `m.image`; `"file"` for `m.file` |
|
||||
| `threadId` | `event.content['m.relates_to']['event_id']` when `rel_type = m.thread` |
|
||||
| `replyToId` | Mosaic ID looked up from `event.content['m.relates_to']['m.in_reply_to']['event_id']` |
|
||||
| `attachments` | Populated from `url` in `m.image` / `m.file` events |
|
||||
| `timestamp` | `new Date(event.origin_server_ts)` |
|
||||
| `metadata` | `{ channelMessageId, roomId, eventType, unsigned }` |
|
||||
|
||||
**Outbound:** Adapter sends `m.room.message` with `msgtype = m.text` (or `m.notice` for system messages). Markdown content is sent with `format = org.matrix.custom.html` and a rendered HTML body.
|
||||
|
||||
---
|
||||
|
||||
### Discord
|
||||
|
||||
| ChannelMessageDto field | Discord equivalent |
|
||||
| ----------------------- | ----------------------------------------------------------------------- |
|
||||
| `id` | Generated UUID; `metadata.channelMessageId` = Discord message snowflake |
|
||||
| `channelId` | Discord channel ID (snowflake string) |
|
||||
| `senderId` | Discord user ID (snowflake) |
|
||||
| `senderKind` | `"user"` for human members; `"agent"` for bot messages |
|
||||
| `content` | `message.content` |
|
||||
| `contentKind` | `"markdown"` (Discord uses a markdown-like syntax natively) |
|
||||
| `threadId` | `message.thread.id` when the message is inside a thread channel |
|
||||
| `replyToId` | Mosaic ID looked up from `message.referenced_message.id` |
|
||||
| `attachments` | `message.attachments` mapped to `ChannelAttachmentDto` |
|
||||
| `timestamp` | `new Date(message.timestamp)` |
|
||||
| `metadata` | `{ channelMessageId, guildId, channelType, mentions, embeds }` |
|
||||
|
||||
**Outbound:** Adapter calls Discord REST `POST /channels/{id}/messages`. Markdown content is sent as-is (Discord renders it). For `contentKind = "code"` the adapter wraps in triple-backtick fences with the `metadata.language` tag.
|
||||
|
||||
### Discord routing and thread policy
|
||||
|
||||
A configured Discord binding maps `(guildId, parentChannelId)` to a stable logical agent and a trusted gateway agent-config ID. Gateway verifies that configuration's name matches the binding logical agent before session creation. The stable conversation handle is derived from logical agent plus response channel/thread and never includes the active harness, provider, model, process, or agent-config ID.
|
||||
|
||||
| Inbound location/trigger | Conversation and response target |
|
||||
| ------------------------------------------ | --------------------------------------------------------------- |
|
||||
| Authorized untagged parent-channel message | Parent channel; response is sent in-channel |
|
||||
| Authorized bot mention in parent channel | Thread already attached to that message, or a new public thread |
|
||||
| Authorized message already in a thread | Existing thread; no repeated mention and no nested thread |
|
||||
| `/approve` or `/stop <approval>` | Current parent/thread durable session; no new topic is created |
|
||||
|
||||
Authorization order is fixed: guild allowlist → parent-channel allowlist → user allowlist → configured binding/pairing → operation role → per-user/channel message and thread rate limits → thread creation/dispatch. A normal Discord channel's category parent is never treated as the thread authorization parent. If requested thread creation fails, dispatch does not occur because the adapter cannot honor the response target.
|
||||
|
||||
### Discord service ingress security
|
||||
|
||||
The Discord adapter is an authenticated gateway service, not an anonymous Socket.IO client. It presents `DISCORD_SERVICE_TOKEN` during its `/chat` connection and signs each inbound envelope using HMAC-SHA-256. The envelope contains the Discord native message ID and a generated correlation ID. Gateway verifies the service credential, signature, and configured guild/channel/user allowlists before agent dispatch, then rejects duplicate native message IDs inside its bounded replay window. All three allowlists are default-deny and required when the Discord plugin is enabled. The service credential is injected at runtime and is never logged or included in protocol payloads.
|
||||
|
||||
---
|
||||
|
||||
### Telegram
|
||||
|
||||
| ChannelMessageDto field | Telegram equivalent |
|
||||
| ----------------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| `id` | Generated UUID; `metadata.channelMessageId` = Telegram `message_id` (integer) |
|
||||
| `channelId` | Telegram `chat_id` (integer as string) |
|
||||
| `senderId` | Telegram `from.id` (integer as string) |
|
||||
| `senderKind` | `"user"` for human senders; `"agent"` for bot-originated messages |
|
||||
| `content` | `message.text` or `message.caption` |
|
||||
| `contentKind` | `"text"` for plain; `"markdown"` if `parse_mode = MarkdownV2`; `"image"` for `photo`; `"file"` for `document` |
|
||||
| `threadId` | `message.message_thread_id` (for supergroup topics) |
|
||||
| `replyToId` | Mosaic ID looked up from `message.reply_to_message.message_id` |
|
||||
| `attachments` | `photo`, `document`, `video` fields mapped to `ChannelAttachmentDto` |
|
||||
| `timestamp` | `new Date(message.date * 1000)` |
|
||||
| `metadata` | `{ channelMessageId, chatType, fromUsername, forwardFrom }` |
|
||||
|
||||
**Outbound:** Adapter calls Telegram Bot API `sendMessage` with `parse_mode = MarkdownV2` for markdown content. For `contentKind = "image"` or `"file"` it uses `sendPhoto` / `sendDocument`.
|
||||
|
||||
---
|
||||
|
||||
### TUI (Terminal UI)
|
||||
|
||||
The TUI adapter bridges Mosaic's terminal interface (`packages/cli`) to the channel protocol so that TUI sessions can be treated as a first-class channel.
|
||||
|
||||
| ChannelMessageDto field | TUI equivalent |
|
||||
| ----------------------- | ------------------------------------------------------------------ |
|
||||
| `id` | Generated UUID (TUI has no native message IDs) |
|
||||
| `channelId` | `"tui:<conversationId>"` — the active conversation ID |
|
||||
| `senderId` | Authenticated Mosaic `userId` |
|
||||
| `senderKind` | `"user"` for human input; `"agent"` for agent replies |
|
||||
| `content` | Raw text from stdin / agent output |
|
||||
| `contentKind` | `"text"` for input; `"markdown"` for agent responses |
|
||||
| `threadId` | Not used (TUI sessions are linear) |
|
||||
| `replyToId` | Not used |
|
||||
| `attachments` | File paths dragged/pasted into the TUI; resolved to `file://` URLs |
|
||||
| `timestamp` | `new Date()` at the moment of send |
|
||||
| `metadata` | `{ conversationId, sessionId, ttyWidth, colorSupport }` |
|
||||
|
||||
**Outbound:** The adapter writes rendered content to stdout. Markdown is rendered via a terminal markdown renderer (e.g. `marked-terminal`). Code blocks are syntax-highlighted when `metadata.colorSupport = true`.
|
||||
|
||||
---
|
||||
|
||||
### WebUI
|
||||
|
||||
The WebUI adapter connects the Next.js frontend (`apps/web`) to the channel protocol over the existing Socket.IO gateway (`apps/gateway`).
|
||||
|
||||
| ChannelMessageDto field | WebUI equivalent |
|
||||
| ----------------------- | ------------------------------------------------------------ |
|
||||
| `id` | Generated UUID; echoed back in the WebSocket event |
|
||||
| `channelId` | `"webui:<conversationId>"` |
|
||||
| `senderId` | Authenticated Mosaic `userId` |
|
||||
| `senderKind` | `"user"` for browser input; `"agent"` for agent responses |
|
||||
| `content` | Message text from the input field |
|
||||
| `contentKind` | `"text"` or `"markdown"` |
|
||||
| `threadId` | Not used (conversation model handles threading) |
|
||||
| `replyToId` | Message ID the user replied to (UI reply affordance) |
|
||||
| `attachments` | Files uploaded via the file picker; stored to object storage |
|
||||
| `timestamp` | `new Date()` at send, or server timestamp from event |
|
||||
| `metadata` | `{ conversationId, sessionId, clientTimezone, userAgent }` |
|
||||
|
||||
**Outbound:** Adapter emits a `chat:message` Socket.IO event. The WebUI React component receives it and appends to the conversation list. Markdown content is rendered client-side via the existing markdown renderer component.
|
||||
|
||||
---
|
||||
|
||||
## Identity Mapping
|
||||
|
||||
Gateway identity-linking policy resolves a channel-native user identifier to a Mosaic `userId` and produces `ChannelAuthorizedPrincipalDto`. Adapters provide native identity evidence but cannot self-authorize Mosaic scope. Discord currently uses configuration-owned paired users; database-backed linking remains the canonical direction for dynamic Matrix/Slack identity.
|
||||
|
||||
The implementation must query a `channel_identities` table (or equivalent) keyed on `(channel_name, channel_user_id)`. When no mapping exists the method returns `null` and the message is treated as anonymous (no Mosaic session context).
|
||||
|
||||
```
|
||||
channel_identities
|
||||
channel_name TEXT -- e.g. "matrix", "discord"
|
||||
channel_user_id TEXT -- channel-native user identifier
|
||||
mosaic_user_id TEXT -- FK to users.id
|
||||
linked_at TIMESTAMP
|
||||
PRIMARY KEY (channel_name, channel_user_id)
|
||||
```
|
||||
|
||||
Identity linking flows (OAuth dance, deep-link verification token, etc.) are out of scope for this document and will be specified in a separate identity-linking protocol document.
|
||||
|
||||
---
|
||||
|
||||
## Error Handling Conventions
|
||||
|
||||
- `start()` must establish the native channel transport or throw a structured connection error. An adapter hosted inside the gateway must not wait for a loopback connection to that same not-yet-listening process; it starts the native transport, lets Socket.IO reconnect, and reports `degraded` until both links are ready.
|
||||
- `ChannelEgressPort.send()` implementations must throw a typed terminal error for revoked auth, an invalid route, or a missing channel. Only transient rate/network/server failures are retried with bounded exponential backoff; Discord retries reuse a stable enforced nonce to prevent duplicate chunks, while permanent 4xx failures are not retried.
|
||||
- `health()` must never throw — it returns `{ status: 'disconnected' }` on error.
|
||||
- Adapters must emit structured logs with `{ channel: adapter.name, event, ... }` metadata for observability.
|
||||
|
||||
---
|
||||
|
||||
## Versioning
|
||||
|
||||
The `ChannelMessageDto` protocol follows semantic versioning. Non-breaking field additions (new optional fields) are minor version bumps. Breaking changes (type changes, required field additions) require a major version bump and a migration guide.
|
||||
|
||||
Current version: **1.0.0**
|
||||
|
||||
---
|
||||
|
||||
## M7-003: Matrix Integration Design
|
||||
|
||||
### Homeserver Choice
|
||||
|
||||
Mosaic uses **Conduit** as the Matrix homeserver. Conduit is written in Rust, ships as a single binary, and has minimal operational overhead compared to Synapse or Dendrite. It supports the full Matrix Client-Server and Application Service APIs required by Mosaic.
|
||||
|
||||
Recommended deployment: Conduit runs as a Docker container alongside the Mosaic stack. A single Conduit instance is sufficient for most self-hosted deployments. Conduit's embedded RocksDB storage means no separate database is required for the homeserver itself.
|
||||
|
||||
### Appservice Registration
|
||||
|
||||
Mosaic registers with the Conduit homeserver as a Matrix **Application Service (appservice)**. This gives Mosaic the ability to:
|
||||
|
||||
- Create and control ghost users (virtual Matrix users representing Mosaic agents and provisioned accounts).
|
||||
- Receive all events sent to rooms within the appservice's namespace without polling.
|
||||
- Send events on behalf of ghost users without separate authentication.
|
||||
|
||||
Registration is done via a YAML registration file (`mosaic-appservice.yaml`) placed in Conduit's configuration directory:
|
||||
|
||||
```yaml
|
||||
id: mosaic
|
||||
url: http://gateway:3000/_matrix/appservice
|
||||
as_token: <random-secret>
|
||||
hs_token: <random-secret>
|
||||
sender_localpart: mosaic-bot
|
||||
namespaces:
|
||||
users:
|
||||
- exclusive: true
|
||||
regex: '@mosaic_.*:homeserver'
|
||||
rooms:
|
||||
- exclusive: false
|
||||
regex: '.*'
|
||||
aliases:
|
||||
- exclusive: true
|
||||
regex: '#mosaic-.*:homeserver'
|
||||
```
|
||||
|
||||
The gateway exposes `/_matrix/appservice` endpoints to receive push events from Conduit. The `as_token` and `hs_token` are stored in Vault and injected at startup.
|
||||
|
||||
### Room ↔ Conversation Mapping
|
||||
|
||||
Each Mosaic conversation maps to a single Matrix room. The mapping is stored in the database:
|
||||
|
||||
```
|
||||
conversation_matrix_rooms
|
||||
conversation_id TEXT -- FK to conversations.id
|
||||
room_id TEXT -- Matrix room ID (!roomid:homeserver)
|
||||
created_at TIMESTAMP
|
||||
PRIMARY KEY (conversation_id)
|
||||
```
|
||||
|
||||
Room creation is handled by the appservice on the first Matrix access to a conversation. Room names follow the pattern `Mosaic: <conversation title>`. Room topics contain the conversation ID for correlation.
|
||||
|
||||
When a conversation is deleted or archived in Mosaic, the corresponding Matrix room is tombstoned (m.room.tombstone event) and the room is left in a read-only state.
|
||||
|
||||
### Space ↔ Team Mapping
|
||||
|
||||
Each Mosaic team maps to a Matrix **Space**. Spaces are Matrix rooms with a special `m.space` type that can contain child rooms.
|
||||
|
||||
```
|
||||
team_matrix_spaces
|
||||
team_id TEXT -- FK to teams.id
|
||||
space_id TEXT -- Matrix room ID of the Space
|
||||
created_at TIMESTAMP
|
||||
PRIMARY KEY (team_id)
|
||||
```
|
||||
|
||||
When a conversation room is shared with a team, the appservice adds it to the team's Space via `m.space.child` state events. Removing the share removes the child relationship.
|
||||
|
||||
### Agent Ghost Users
|
||||
|
||||
Each Mosaic agent is represented in Matrix as an **appservice ghost user**:
|
||||
|
||||
- Matrix user ID format: `@mosaic_agent_<agentId>:homeserver`
|
||||
- Display name: the agent's human-readable name (e.g. "Mosaic Assistant")
|
||||
- Avatar: optional, configurable per agent
|
||||
|
||||
Ghost users are registered lazily — the appservice creates the ghost on first use. Ghost users are controlled exclusively by the appservice; they cannot log in via Matrix client credentials.
|
||||
|
||||
When an agent sends a message via the gateway, the Matrix adapter sends the event using `user_id` impersonation on the appservice's client endpoint, causing the message to appear as if sent by the ghost user.
|
||||
|
||||
### Power Levels
|
||||
|
||||
Power levels in each Mosaic-managed room are set as follows:
|
||||
|
||||
| Entity | Power Level | Rationale |
|
||||
| ------------------------------------- | -------------- | -------------------------------------- |
|
||||
| Mosaic appservice bot (`@mosaic-bot`) | 100 (Admin) | Room management and moderation |
|
||||
| Human Mosaic users | 50 (Moderator) | Can kick, redact, and invite |
|
||||
| Agent ghost users | 0 (Default) | Message-only; cannot modify room state |
|
||||
|
||||
This arrangement ensures human users retain full control. An agent cannot modify room settings, kick members, or take administrative actions. Humans with moderator power can redact agent messages and intervene in ongoing conversations.
|
||||
|
||||
```
|
||||
mermaid
|
||||
graph TD
|
||||
A[Mosaic Admin] -->|invites| B[Human User]
|
||||
B -->|joins| C[Matrix Room / Conversation]
|
||||
D[Agent Ghost User] -->|sends messages to| C
|
||||
B -->|can redact/kick| D
|
||||
E[Mosaic Bot] -->|manages room state| C
|
||||
style A fill:#4a9eff
|
||||
style B fill:#4a9eff
|
||||
style D fill:#aaaaaa
|
||||
style E fill:#ff9944
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## M7-004: Conversation Multiplexing
|
||||
|
||||
### Architecture Overview
|
||||
|
||||
A single Mosaic conversation can be accessed simultaneously from multiple surfaces: TUI, WebUI, and Matrix. The gateway is the **single source of truth** for all conversation state. Each surface is a thin client that renders gateway-owned data.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Gateway (NestJS) │
|
||||
│ │
|
||||
│ ConversationService ←→ MessageBus │
|
||||
│ │ │ │
|
||||
│ [DB: PostgreSQL] [Fanout: Valkey Pub/Sub] │
|
||||
│ │ │
|
||||
│ ┌─────────────────────┼──────────────┐ │
|
||||
│ │ │ │ │
|
||||
│ Socket.IO Socket.IO Matrix │ │
|
||||
│ (TUI adapter) (WebUI adapter) (appservice)│ │
|
||||
└──────────┼─────────────────────┼──────────────┘ │
|
||||
│ │ │
|
||||
CLI/TUI Browser Matrix
|
||||
Client
|
||||
```
|
||||
|
||||
### Real-Time Sync Flow
|
||||
|
||||
1. A message arrives on any surface (TUI keystroke, browser send, Matrix event).
|
||||
2. The surface's adapter normalizes the message to `ChannelMessageDto` and delivers it to `ConversationService`.
|
||||
3. `ConversationService` persists the message to PostgreSQL, assigns a canonical `id`, and publishes a `message:new` event to the Valkey pub/sub channel keyed by `conversationId`.
|
||||
4. All active surfaces subscribed to that `conversationId` receive the fanout event and push it to their respective clients:
|
||||
- TUI adapter: writes rendered output to the connected terminal session.
|
||||
- WebUI adapter: emits a `chat:message` Socket.IO event to all browser sessions joined to that conversation.
|
||||
- Matrix adapter: sends an `m.room.message` event to the conversation's Matrix room.
|
||||
|
||||
This ensures that a message typed in the TUI appears in the browser and in Matrix within the same round-trip latency as the Valkey fanout (typically <10 ms on co-located infrastructure).
|
||||
|
||||
### Surface-to-Transport Mapping
|
||||
|
||||
| Surface | Transport to Gateway | Fanout Transport from Gateway |
|
||||
| ------- | ------------------------------------------ | ----------------------------- |
|
||||
| TUI | HTTPS REST + SSE or WebSocket | Socket.IO over stdio proxy |
|
||||
| WebUI | Socket.IO (browser) | Socket.IO emit |
|
||||
| Matrix | Matrix Client-Server API (appservice push) | Matrix `m.room.message` send |
|
||||
|
||||
### Conflict Resolution
|
||||
|
||||
- **Messages**: Append-only. Messages are never edited in-place in Mosaic's canonical store. Matrix edit events (`m.replace`) are treated as new messages with `replyToId` pointing to the original, preserving the full audit trail.
|
||||
- **Metadata (title, tags, archived state)**: Last-write-wins. The timestamp of the most recent write wins. Concurrent metadata updates from different surfaces are serialized through `ConversationService`; the final database write reflects the last persisted value.
|
||||
- **Conversation membership**: Set-merge semantics. Adding a user from any surface is additive. Removal requires an explicit delete action and is not overwritten by concurrent adds.
|
||||
|
||||
### Session Isolation
|
||||
|
||||
Multiple TUI sessions or browser tabs connected to the same conversation receive all fanout messages independently. Each session maintains its own scroll position and local ephemeral state (typing indicator, draft text). Gateway does not synchronize ephemeral state across sessions.
|
||||
|
||||
---
|
||||
|
||||
## M7-005: Remote Auth Bridging
|
||||
|
||||
### Overview
|
||||
|
||||
Matrix users authenticate to Mosaic by linking their Matrix identity to an existing Mosaic account. There are two flows: token linking (primary) and OAuth bridge (alternative). Once linked, the Matrix session is persistent — there is no periodic login/logout cycle.
|
||||
|
||||
### Token Linking Flow
|
||||
|
||||
1. A Mosaic admin or the user themselves generates a short-lived link token via the Mosaic web UI or API (`POST /auth/channel-link-token`). The token is a cryptographically random 32-byte hex string with a 15-minute TTL stored in Valkey.
|
||||
2. The user opens a Matrix client and sends a DM to `@mosaic-bot:homeserver`.
|
||||
3. The user sends the command: `!link <token>`
|
||||
4. The appservice receives the `m.room.message` event in the DM room, extracts the token, and calls `AuthService.linkChannelIdentity({ channel: 'matrix', channelUserId: matrixUserId, token })`.
|
||||
5. `AuthService` validates the token, retrieves the associated `mosaicUserId`, and writes a row to `channel_identities`.
|
||||
6. The appservice sends a confirmation reply in the DM room and invites the now-linked user to their personal Matrix Space.
|
||||
|
||||
```
|
||||
User (Matrix) @mosaic-bot Mosaic Gateway
|
||||
│ │ │
|
||||
│ DM: !link <token> │ │
|
||||
│────────────────────▶│ │
|
||||
│ │ POST /auth/link │
|
||||
│ │─────────────────────▶│
|
||||
│ │ 200 OK │
|
||||
│ │◀─────────────────────│
|
||||
│ ✓ Linked! Joining │ │
|
||||
│ your Space now │ │
|
||||
│◀────────────────────│ │
|
||||
```
|
||||
|
||||
### OAuth Bridge Flow
|
||||
|
||||
An alternative flow for users who prefer browser-based authentication:
|
||||
|
||||
1. The Mosaic bot sends the user a Matrix message containing an OAuth URL: `https://mosaic.example.com/auth/matrix-link?state=<nonce>&matrix_user=<encoded_mxid>`
|
||||
2. The user opens the URL in a browser. If not already logged in to Mosaic, they are redirected through the standard BetterAuth login flow.
|
||||
3. On successful authentication, Mosaic records the `channel_identities` row linking `matrix_user` to the authenticated `mosaicUserId`.
|
||||
4. The gateway sends a Matrix event to the pending DM room confirming the link.
|
||||
|
||||
### Invite-Based Provisioning
|
||||
|
||||
When a Mosaic admin adds a new user account, the provisioning flow optionally associates a Matrix user ID with the new account at creation time:
|
||||
|
||||
1. Admin provides `matrixUserId` when creating the account (`POST /admin/users`).
|
||||
2. `UserService` writes the `channel_identities` row immediately.
|
||||
3. The Matrix adapter's provisioning hook fires, and the appservice:
|
||||
- Creates the user's personal Matrix Space (if not already existing).
|
||||
- Sends an invite to the Matrix user for their personal Space.
|
||||
- Sends a welcome DM from `@mosaic-bot` with onboarding instructions.
|
||||
|
||||
The invited user does not need to complete any linking step — the association is pre-established by the admin.
|
||||
|
||||
### Session Lifecycle
|
||||
|
||||
Matrix sessions for linked users are persistent and long-lived. Unlike TUI sessions (which terminate when the terminal process exits), a Matrix user's access to their rooms remains intact as long as:
|
||||
|
||||
- Their Mosaic account is active (not suspended or deleted).
|
||||
- Their `channel_identities` row exists (link not revoked).
|
||||
- They remain members of the relevant Matrix rooms.
|
||||
|
||||
Revoking a Matrix link (`DELETE /auth/channel-link/matrix/<matrixUserId>`) removes the `channel_identities` row and causes gateway principal resolution to deny the identity. The appservice optionally kicks the Matrix user from all Mosaic-managed rooms as part of the revocation flow (configurable, default: off).
|
||||
|
||||
---
|
||||
|
||||
## M7-006: Agent-to-Agent Communication via Matrix
|
||||
|
||||
### Dedicated Agent Rooms
|
||||
|
||||
When two Mosaic agents need to coordinate, a dedicated Matrix room is created for their dialogue. This provides a persistent, auditable channel for structured inter-agent communication that humans can observe.
|
||||
|
||||
Room naming convention:
|
||||
|
||||
```
|
||||
#mosaic-agents-<agentA>-<agentB>:homeserver
|
||||
```
|
||||
|
||||
Where `agentA` and `agentB` are the Mosaic agent IDs sorted lexicographically (to ensure the same room is used regardless of which agent initiates). The room alias is registered by the appservice.
|
||||
|
||||
```
|
||||
agent_rooms
|
||||
room_id TEXT -- Matrix room ID
|
||||
agent_a_id TEXT -- FK to agents.id (lexicographically first)
|
||||
agent_b_id TEXT -- FK to agents.id (lexicographically second)
|
||||
created_at TIMESTAMP
|
||||
PRIMARY KEY (agent_a_id, agent_b_id)
|
||||
```
|
||||
|
||||
### Room Membership and Power Levels
|
||||
|
||||
| Entity | Power Level |
|
||||
| ---------------------------------- | ------------------------------------ |
|
||||
| Mosaic appservice bot | 100 (Admin) |
|
||||
| Human observers (invited) | 50 (Moderator, read-only by default) |
|
||||
| Agent ghost users (agentA, agentB) | 0 (Default — message send only) |
|
||||
|
||||
Humans are invited to agent rooms with a read-only intent. By convention, human messages in agent rooms are prefixed with `[HUMAN]` and treated as interrupts by the gateway. Agents are instructed (via system prompt) to pause and acknowledge human messages before resuming their dialogue.
|
||||
|
||||
### Message Format
|
||||
|
||||
Agents communicate using **structured JSON** embedded in Matrix event content. The Matrix event type is `m.room.message` with `msgtype: "m.text"` for compatibility. The structured payload is carried in a custom `mosaic.agent_message` field:
|
||||
|
||||
```json
|
||||
{
|
||||
"msgtype": "m.text",
|
||||
"body": "[Agent message — see mosaic.agent_message for structured content]",
|
||||
"mosaic.agent_message": {
|
||||
"schema_version": "1.0",
|
||||
"sender_agent_id": "agent_abc123",
|
||||
"conversation_id": "conv_xyz789",
|
||||
"message_type": "request",
|
||||
"payload": {
|
||||
"action": "summarize",
|
||||
"parameters": { "max_tokens": 500 },
|
||||
"reply_to_event_id": "$previousEventId"
|
||||
},
|
||||
"timestamp_ms": 1711234567890
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `body` field contains a human-readable fallback so the conversation is legible in any Matrix client. The structured payload is parsed exclusively by the gateway's Matrix adapter.
|
||||
|
||||
### Coordination Patterns
|
||||
|
||||
**Request/Response**: Agent A sends a `message_type: "request"` event. Agent B sends a `message_type: "response"` with `reply_to_event_id` referencing Agent A's event. The gateway correlates request/response pairs using the event IDs.
|
||||
|
||||
**Broadcast**: An agent sends a `message_type: "broadcast"` to a multi-agent room (more than two members). All agents in the room receive the event. No response is expected.
|
||||
|
||||
**Delegation**: Agent A sends a `message_type: "delegate"` with a `payload.task` object describing work to be handed off to Agent B. Agent B acknowledges with `message_type: "delegate_ack"` and later sends `message_type: "delegate_complete"` when done.
|
||||
|
||||
```
|
||||
AgentA Gateway AgentB
|
||||
│ delegate(task) │ │
|
||||
│────────────────────▶│ │
|
||||
│ │ Matrix event push │
|
||||
│ │────────────────────▶│
|
||||
│ │ delegate_ack │
|
||||
│ │◀────────────────────│
|
||||
│ │ [AgentB executes] │
|
||||
│ │ delegate_complete │
|
||||
│ │◀────────────────────│
|
||||
│ task result │ │
|
||||
│◀────────────────────│ │
|
||||
```
|
||||
|
||||
### Gateway Mediation
|
||||
|
||||
Agents do not call the Matrix Client-Server API directly. All inter-agent Matrix events are sent and received by the gateway's appservice. This means:
|
||||
|
||||
- The gateway can intercept, log, and rate-limit agent-to-agent messages.
|
||||
- Agents that are offline (no active process) still have their messages delivered; the gateway queues them and delivers on the agent's next activation.
|
||||
- The gateway can inject system messages (e.g. human interrupts, safety stops) into agent rooms without agent cooperation.
|
||||
|
||||
---
|
||||
|
||||
## M7-007: Multi-User Isolation in Matrix
|
||||
|
||||
### Space-per-Team Architecture
|
||||
|
||||
Isolation in Matrix is enforced through the Space hierarchy. Each organizational boundary in Mosaic maps to a distinct Matrix Space:
|
||||
|
||||
| Mosaic entity | Matrix Space | Visibility |
|
||||
| ----------------------------- | -------------- | ----------------- |
|
||||
| Personal workspace (per user) | Personal Space | User only |
|
||||
| Team | Team Space | Team members only |
|
||||
| Public project | (no Space) | Configurable |
|
||||
|
||||
Rooms (conversations) are placed into Spaces based on their sharing configuration. A room can appear in at most one team Space at a time. Moving a room from one team Space to another removes the `m.space.child` link from the old Space and adds it to the new one.
|
||||
|
||||
### Room Visibility Rules
|
||||
|
||||
Matrix room visibility within Conduit is controlled by:
|
||||
|
||||
1. **Join rules**: All Mosaic-managed rooms use `join_rule: invite`. Users cannot discover or join rooms without an explicit invite from the appservice.
|
||||
2. **Space membership**: Rooms appear in a Space's directory only to users who are members of that Space.
|
||||
3. **Room directory**: The server room directory is disabled for Mosaic-managed rooms (`m.room.history_visibility: shared` for team rooms, `m.room.history_visibility: invited` for personal rooms).
|
||||
|
||||
### Personal Space Defaults
|
||||
|
||||
When a user account is created (or linked to Matrix), the appservice provisions a personal Space:
|
||||
|
||||
- Space name: `<username>'s Space`
|
||||
- All conversations the user creates personally are added as children of their personal Space.
|
||||
- No other users are members of this Space by default.
|
||||
- Conversation rooms within the personal Space are only visible and accessible to the owner.
|
||||
|
||||
### Team Shared Rooms
|
||||
|
||||
When a project or conversation is shared with a team:
|
||||
|
||||
1. The appservice adds the room as a child of the team's Space (`m.space.child` state event in the Space room, `m.space.parent` state event in the conversation room).
|
||||
2. All current team members are invited to the conversation room.
|
||||
3. Newly added team members are automatically invited to all shared rooms in the team's Space by the appservice's team membership hook.
|
||||
4. If sharing is revoked, the appservice removes the `m.space.child` link and kicks all team members who joined via the team share (users who were directly invited are unaffected).
|
||||
|
||||
### Encryption
|
||||
|
||||
Encryption is optional and configured per room at creation time. Recommended defaults:
|
||||
|
||||
| Space type | Encryption default | Rationale |
|
||||
| -------------- | ------------------ | -------------------------------------- |
|
||||
| Personal Space | Enabled | Privacy-first for individual users |
|
||||
| Team Space | Disabled | Operational visibility; admin auditing |
|
||||
| Agent rooms | Disabled | Gateway must read structured payloads |
|
||||
|
||||
When encryption is enabled, the appservice's ghost users must participate in key exchange (using Matrix's Olm/Megolm protocol). The gateway holds the device keys for all ghost users it controls. This constraint means encrypted rooms require the gateway to be the E2E session holder — messages are end-to-end encrypted between human clients and gateway-held ghost device keys, not between human clients themselves.
|
||||
|
||||
### Admin Visibility
|
||||
|
||||
A Conduit server administrator can see:
|
||||
|
||||
- Room metadata: names, aliases, topic, membership list.
|
||||
- Unencrypted event content in unencrypted rooms.
|
||||
|
||||
A Conduit server administrator **cannot** see:
|
||||
|
||||
- Content of encrypted rooms (without holding a device key for a room member).
|
||||
|
||||
Mosaic does not grant gateway admin credentials to application-level admin users. The Conduit admin interface is restricted to infrastructure operators. Application-level admins manage users and rooms through the Mosaic API, which interacts with the appservice layer only.
|
||||
|
||||
### Data Retention
|
||||
|
||||
Matrix events in Mosaic-managed rooms follow Mosaic's configurable retention policy:
|
||||
|
||||
```
|
||||
room_retention_policies
|
||||
room_id TEXT -- Matrix room ID (or wildcard pattern)
|
||||
retention_days INT -- NULL = keep forever
|
||||
applies_to TEXT -- "personal" | "team" | "agent" | "all"
|
||||
created_at TIMESTAMP
|
||||
```
|
||||
|
||||
The retention policy is enforced by a background job in the gateway that calls Conduit's admin API to purge events older than the configured threshold. Purged events are removed from the Conduit store but Mosaic's PostgreSQL message store retains the canonical `ChannelMessageDto` record unless the Mosaic retention policy also covers it.
|
||||
|
||||
Default retention values:
|
||||
|
||||
| Room type | Default retention |
|
||||
| --------------------------- | ------------------- |
|
||||
| Personal conversation rooms | 365 days |
|
||||
| Team conversation rooms | 730 days |
|
||||
| Agent-to-agent rooms | 90 days |
|
||||
| System/audit rooms | 1825 days (5 years) |
|
||||
|
||||
Retention settings are configurable by Mosaic admins via the admin API and apply to both the Matrix event store and the Mosaic message store in lockstep.
|
||||
-4
@@ -1,9 +1,5 @@
|
||||
# Compaction observer revocation and runtime generations
|
||||
|
||||
> **Status:** Current contract reference.
|
||||
> **Audience:** Developer and security reviewer.
|
||||
> **Evidence:** Mutator-gate and framework portability acceptance suites consume this page; live deployment gaps remain explicitly labeled below.
|
||||
|
||||
WI-3 connects Claude and Pi compaction/session lifecycle events to the existing authenticated lease-broker state machine. It does not add a second lease store or let runtime hooks assert identity. Each observer inherits the broker-minted session, resolves the current private runtime generation, and sends the existing `revoke_lease` action over the authenticated Unix socket.
|
||||
|
||||
## Observer matrix
|
||||
-4
@@ -1,9 +1,5 @@
|
||||
# Authenticated external lease broker protocol
|
||||
|
||||
> **Status:** Current contract reference.
|
||||
> **Audience:** Developer and security reviewer.
|
||||
> **Evidence:** Lease-broker acceptance suites consume this page; executable behavior remains authoritative in source and tests.
|
||||
|
||||
The compaction-refresh lease broker is a Linux-only, newline-framed JSON protocol over a Unix stream socket. It is runtime-neutral; M1 consumers are limited to Claude and Pi. This is an internal process boundary, not an HTTP API, so it is intentionally absent from OpenAPI.
|
||||
|
||||
The broker, never the caller, obtains `(pid, uid, gid)` from kernel `SO_PEERCRED`. It correlates the PID with `/proc/<pid>/stat` field 22 (`starttime`) and mints `session_id` on `register_anchor`. Presence of `session_id` in that request is refused even when its value is `null` or empty. Later requests must originate from the anchor or a descendant. The broker walks parent PIDs to the `(pid,starttime)` anchor and then rereads every walked PID's starttime before accepting the chain.
|
||||
-4
@@ -1,9 +1,5 @@
|
||||
# WI-1 lease broker security notes
|
||||
|
||||
> **Status:** Current contract reference.
|
||||
> **Audience:** Developer and security reviewer.
|
||||
> **Evidence:** The lease-broker implementation and acceptance material cross-check this boundary; deployment-review requirements remain explicitly labeled below.
|
||||
|
||||
- Trusted identity comes only from Linux `SO_PEERCRED` plus `/proc` starttime, never request identity fields.
|
||||
- Descendant authorization is anchored to `(pid,starttime)` and uses a complete second starttime pass to fail closed on disappearance or PID-reuse races.
|
||||
- Runtime generations are monotonic per anchor; a bump revokes prior-incarnation tokens before persistence commits. WI-3 stores the live generation in an owner-only locked file so same-PID Pi reload/new/resume/fork and Claude resume/clear transitions cannot inherit a VERIFIED lease.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Mos Runtime Portability M1 — Logical Identity and Fencing
|
||||
|
||||
## Boundary
|
||||
|
||||
M1 separates the logical Mosaic agent from any Claude, Pi, Codex, tmux, Matrix, or provider-native session. The normalized identity is:
|
||||
|
||||
```text
|
||||
(tenant_id, logical_agent_id, binding_id)
|
||||
```
|
||||
|
||||
`logical_agent_id` is a server-owned stable identifier. A connector is a replaceable holder of a lease for one binding; it is not the agent identity.
|
||||
|
||||
## Durable lease model
|
||||
|
||||
PostgreSQL table `logical_agent_connector_leases` has one unique row per identity/binding tuple. The current row records:
|
||||
|
||||
- an opaque lease UUID;
|
||||
- connector ID and normalized allowed scopes;
|
||||
- a positive decimal fencing epoch stored as PostgreSQL `bigint`;
|
||||
- acquired, heartbeat, expiry, release, and update timestamps.
|
||||
|
||||
Initial acquisition is insert-only. An existing active row causes `lease_held`. An expired or released row causes `takeover_required`; ordinary acquisition cannot recover it. Authorized takeover uses compare-and-swap against the expected epoch, rotates the lease UUID, and increments the epoch atomically. Heartbeat and release match the full identity, binding, connector, lease UUID, and epoch.
|
||||
|
||||
The companion `connector_lease_audit_log` is append-only metadata. It stores lifecycle event, outcome/reason, identity/binding/connector, epoch, correlation ID, and timestamp. It deliberately excludes scopes, grant objects, payloads, approval references, tokens, and credentials.
|
||||
|
||||
## Execution grants
|
||||
|
||||
`ConnectorLeaseCoordinator` issues a short-lived internal grant only after rereading the durable current lease. Defense-in-depth caps leases at 5 minutes and grants at 30 seconds by default; constructor options may tighten these limits. A grant is bound to tenant, logical agent, binding, connector, lease UUID, scope subset, expiry, and epoch.
|
||||
|
||||
Validation occurs immediately before adapter invocation and rereads PostgreSQL. The adapter receives only `ConnectorExecutionContext`; harness-native schemas remain behind the adapter. Validation denies:
|
||||
|
||||
- grants not minted by the current gateway process (including cloned/forged objects);
|
||||
- expired grants or leases;
|
||||
- released leases;
|
||||
- stale epochs or replaced connector/lease UUIDs;
|
||||
- missing/cross-tenant/cross-agent/cross-binding leases;
|
||||
- scopes not authorized by both grant and current lease.
|
||||
|
||||
A gateway restart intentionally invalidates process-local grants. The durable lease and epoch survive, and a fresh grant may be issued only after current-lease and gateway-policy validation.
|
||||
|
||||
## Concurrency and side-effect rule
|
||||
|
||||
The database CAS determines the sole current holder. A successful takeover makes every old-epoch validation fail. Connector adapters must consume and propagate the normalized lease epoch/context so downstream effect boundaries can also fence races that occur after gateway validation.
|
||||
|
||||
M1 does not provide exactly-once receipts or a side-effect journal. Those remain later #754 work; callers must not infer exactly-once delivery from lease fencing.
|
||||
|
||||
## Extension boundary
|
||||
|
||||
`ConnectorLeaseService` is the gateway-owned policy surface. Every policy decision receives the normalized requested scopes and TTL (or explicit `null` where no TTL applies), so a concrete policy can enforce least privilege and duration limits. Its production default policy denies every lease/grant operation until a server-configured connector policy is supplied. No M1 HTTP endpoint accepts caller-controlled tenant or logical identity, and no concrete Claude/Pi/Codex adapter or channel cutover is included.
|
||||
-4
@@ -1,9 +1,5 @@
|
||||
# Whole mutator-class lease gate
|
||||
|
||||
> **Status:** Current contract reference.
|
||||
> **Audience:** Developer and security reviewer.
|
||||
> **Evidence:** Runtime launch-guard and mutator-gate tests cross-check this boundary; parser residuals and deployment gaps remain explicitly labeled below.
|
||||
|
||||
WI-2 adds the framework-native authorization boundary for Claude (including the supported Claudex overlay) and Pi. Every runtime-reported tool name reaches the lease broker before execution. The gate classifies capabilities by the whole tool class; it never parses a Bash command to decide whether that particular string looks read-only.
|
||||
|
||||
## Default-deny policy
|
||||
@@ -1,35 +0,0 @@
|
||||
# Documentation Archive
|
||||
|
||||
> **Status:** Current archive index. Pages linked here are historical or superseded and are not current product, operator, or developer guidance.
|
||||
|
||||
Use [`docs/README.md`](../README.md) for current placement and source-of-truth rules. Historical pages remain discoverable here only when retaining their context is useful; each migration should identify a replacement or explain why the record is retained.
|
||||
|
||||
## Archived TUI workstream
|
||||
|
||||
The following branch-specific records are retained because their implementation claims and worktree paths no longer match the current checkout:
|
||||
|
||||
- [`TUI improvements PRD`](tui/PRD-TUI_Improvements.md) — historical Phase 7 requirements; it names the deleted `packages/cli` package.
|
||||
- [`TUI improvements task ledger`](tui/TASKS-TUI_Improvements.md) — historical task/status record; its relative PRD link remains valid within this archive directory.
|
||||
|
||||
Do not use these pages as instructions for the current TUI. Current TUI implementation is under `packages/mosaic`; any new requirements require a separately approved plan or PRD.
|
||||
|
||||
## Archived missions
|
||||
|
||||
- [`Mission archive index`](missions/README.md) — completed and superseded CLI, harness, install UX, and storage-abstraction mission records.
|
||||
|
||||
Archived mission manifests and task ledgers preserve their original status and context. They do not replace current orchestrator-owned [`docs/TASKS.md`](../TASKS.md) or authorize old installation procedures.
|
||||
|
||||
## Archived planning
|
||||
|
||||
- [`Planning archive index`](planning/README.md) — historical briefs, reviews, and work-package specifications.
|
||||
- [`Monorepo consolidation bundle`](planning/monorepo-consolidation/README.md) — prior Forge, MACP, and framework-plugin consolidation planning. Current package existence does not validate every historical criterion.
|
||||
|
||||
## Archived work records
|
||||
|
||||
- [`Work-record archive`](work-records/README.md) — unreferenced historical task scratchpads retained as evidence, not active status or guidance.
|
||||
|
||||
## Retention rules
|
||||
|
||||
- Preserve historical wording unless a migration task explicitly requires a rewrite.
|
||||
- Label replacements and current status in the owning index rather than silently reviving archived claims.
|
||||
- Do not link archive pages from current workflow instructions as if they were current.
|
||||
@@ -1,37 +0,0 @@
|
||||
# Archived Missions
|
||||
|
||||
> **Status:** Historical mission index. These records describe completed or superseded delivery work and are not current task state, requirements, installation guidance, or command authority.
|
||||
|
||||
## CLI unification — 2026-04-04
|
||||
|
||||
- [Mission manifest](cli-unification-20260404/MISSION-MANIFEST.md)
|
||||
- [Task ledger](cli-unification-20260404/TASKS.md)
|
||||
|
||||
## Harness foundation — 2026-03-21
|
||||
|
||||
- [Mission manifest](harness-20260321/MISSION-MANIFEST.md)
|
||||
- [Scoped PRD](harness-20260321/PRD.md)
|
||||
|
||||
## Install UX hardening — 2026-04-05
|
||||
|
||||
- [Mission manifest](install-ux-hardening-20260405/MISSION-MANIFEST.md)
|
||||
- [Task ledger](install-ux-hardening-20260405/TASKS.md)
|
||||
|
||||
## Install UX v2 — 2026-04-05
|
||||
|
||||
- [Mission manifest](install-ux-v2-20260405/MISSION-MANIFEST.md)
|
||||
- [Task ledger](install-ux-v2-20260405/TASKS.md)
|
||||
- [IUV-M03 design](install-ux-v2-20260405/iuv-m03-design.md)
|
||||
- [Orchestrator scratchpad](install-ux-v2-20260405/scratchpad.md)
|
||||
|
||||
## Storage abstraction retrofit
|
||||
|
||||
- [Task ledger](storage-abstraction/TASKS.md)
|
||||
|
||||
Historical statuses, commands, package paths, and completion claims are retained for provenance and may not match the current checkout. Use [`docs/TASKS.md`](../../TASKS.md) only for orchestrator-owned current task state.
|
||||
|
||||
## Related
|
||||
|
||||
- [[archive/README|Documentation archive]]
|
||||
- [[SITEMAP|Documentation sitemap]]
|
||||
- [[reports/README|Documentation reports]]
|
||||
@@ -12,7 +12,7 @@
|
||||
**Progress:** 3 / 3 milestones
|
||||
**Status:** complete
|
||||
**Last Updated:** 2026-04-05 (mission complete)
|
||||
**Parent Mission:** [cli-unification-20260404](../cli-unification-20260404/MISSION-MANIFEST.md) (complete)
|
||||
**Parent Mission:** [cli-unification-20260404](./archive/missions/cli-unification-20260404/MISSION-MANIFEST.md) (complete)
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
**Status:** complete
|
||||
**Last Updated:** 2026-04-19 (archived during MVP manifest authoring; IUV-M03 substantively shipped via PR #446 — drill-down menu + provider-first flow + quick start; releases 0.0.27 → 0.0.29)
|
||||
**Archived to:** `docs/archive/missions/install-ux-v2-20260405/`
|
||||
**Parent Mission:** [install-ux-hardening-20260405](../install-ux-hardening-20260405/MISSION-MANIFEST.md) (complete — `mosaic-v0.0.25`)
|
||||
**Parent Mission:** [install-ux-hardening-20260405](./archive/missions/install-ux-hardening-20260405/MISSION-MANIFEST.md) (complete — `mosaic-v0.0.25`)
|
||||
|
||||
## Context
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Archived planning records
|
||||
|
||||
> **Status:** Historical planning index. These records preserve prior intent and review context; they are not current requirements, task state, implementation evidence, or operational authority.
|
||||
|
||||
## Monorepo consolidation
|
||||
|
||||
- [Planning bundle](monorepo-consolidation/README.md) — historical brief, board review, and Forge/MACP/framework-plugin work-package specifications.
|
||||
|
||||
## Legacy plans and deferred stubs
|
||||
|
||||
- [Legacy planning index](legacy/README.md) — unreferenced implementation plans, a superseded SSO setup record, and explicitly deferred design stubs.
|
||||
- [Archived Matrix/MACP proposals](matrix-macp/README.md) — historical draft communications and deployment RFCs for functionality not established by current source/tests.
|
||||
- [Archived standalone designs](designs/README.md) — historical prerelease-pipeline and storage-abstraction designs.
|
||||
|
||||
Use current package source, tests, audience guides, and approved control documents for present behavior and status.
|
||||
@@ -1,8 +0,0 @@
|
||||
# Archived standalone designs
|
||||
|
||||
> **Status:** Historical design records. These files moved byte-identically from migration quarantine on 2026-08-10 and are not current implementation or release contracts.
|
||||
|
||||
- [npm prerelease `@next` lane](prerelease-next-dist-tag-pipeline.md) — prior release-pipeline design; verify current CI and package scripts before use.
|
||||
- [Storage and queue abstraction](storage-abstraction-middleware.md) — prior middleware/tier design. Current storage abstractions exist, but this record does not prove its complete target architecture or operational procedures.
|
||||
|
||||
Use current package source, manifests, tests, and canonical safety guidance for present behavior. The coupled #791 upgrade design and normative framework constitution remain in migration quarantine pending their owning workstreams.
|
||||
@@ -1,28 +0,0 @@
|
||||
# Legacy plans and deferred design stubs
|
||||
|
||||
> **Status:** Historical planning archive. These files preserve prior proposals and implementation approaches; they are not proof of shipped behavior or authority to run commands.
|
||||
|
||||
The records below moved byte-identically from migration quarantine on 2026-08-10. Validate every claim against current source, tests, configuration, and safety policy before reuse.
|
||||
|
||||
## Implementation plans
|
||||
|
||||
- [Gateway security hardening](2026-03-13-gateway-security-hardening.md)
|
||||
- [Agent platform architecture](2026-03-15-agent-platform-architecture.md)
|
||||
- [Wave 2 TUI layout and navigation](2026-03-15-wave2-tui-layout-navigation.md)
|
||||
- [Hermes–Mosaic alignment](2026-05-06-hermes-mosaic-alignment.md)
|
||||
- [Coordination resilience](2026-05-07-coordination-resilience.md)
|
||||
- [Gateway token recovery](gateway-token-recovery.md)
|
||||
|
||||
## Setup record
|
||||
|
||||
- [Authentik SSO setup](authentik-sso-setup.md) — superseded for current administration by the canonical [SSO provider guide](../../../ADMIN-GUIDE/security/sso-providers.md).
|
||||
|
||||
## Explicitly deferred stubs
|
||||
|
||||
- [Chroot agent sandboxing](chroot-sandboxing.md)
|
||||
- [Gatekeeper service](gatekeeper-service.md)
|
||||
- [Task queue unification](task-queue-unification.md)
|
||||
|
||||
## Exclusions
|
||||
|
||||
The Agent Reflection PRD remains in quarantine because a live MACP test names its intended canonical path. The WebUI/Fleet Claude bridge draft remains authority-gated and coupled to Fleet decisions. Neither was moved in this archival slice.
|
||||
@@ -1,10 +0,0 @@
|
||||
# Archived Matrix/MACP proposals
|
||||
|
||||
> **Status:** Historical draft proposals. These records moved byte-identically from migration quarantine on 2026-08-10 and have no implementation or operational authority.
|
||||
|
||||
- [RFC-001: MACP Matrix-native communications](rfc-001-macp-matrix-native.md)
|
||||
- [RFC-002: install, configuration, and topology](rfc-002-install-config-topology.md)
|
||||
|
||||
Current source and focused tests do not establish the proposed Matrix adapter, identity mapping, persistence, homeserver/appservice topology, or federation operations. See the canonical [channel protocol](../../../DEVELOPER-GUIDE/architecture/channel-protocol.md) for the implemented Discord boundary and explicit Matrix limitations.
|
||||
|
||||
Do not use these archived RFCs as deployment instructions or as evidence that Matrix/MACP functionality shipped.
|
||||
@@ -1,19 +0,0 @@
|
||||
# Monorepo consolidation planning bundle
|
||||
|
||||
> **Status:** Historical planning evidence. The five source records were moved byte-identically from migration quarantine on 2026-08-10.
|
||||
|
||||
This bundle records the decision and proposed work packages for consolidating prior Forge, MACP, and OpenClaw framework work into this monorepo.
|
||||
|
||||
## Records
|
||||
|
||||
- [Consolidation brief](brief.md) — original scope, target layout, constraints, and success criteria.
|
||||
- [Board review](board-review.md) — historical deliberation and conditional approval.
|
||||
- [WP1: Forge package](wp1-forge-package.md) — proposed TypeScript Forge implementation.
|
||||
- [WP2: MACP package](wp2-macp-package.md) — proposed protocol, gate, credential, and event implementation.
|
||||
- [WP3: Mosaic framework plugin](wp3-mosaic-framework-plugin.md) — proposed OpenClaw framework plugin port.
|
||||
|
||||
## Current boundary
|
||||
|
||||
`packages/forge`, `packages/macp`, and `plugins/mosaic-framework` exist in the current checkout. That existence is sufficient to classify this bundle as historical planning, but it does **not** prove that every stated success criterion, integration, coverage target, or behavior remains satisfied.
|
||||
|
||||
Use current package source, manifests, and tests for implementation truth. Do not use this bundle as an active task ledger or as authority to change package behavior.
|
||||
@@ -1,19 +0,0 @@
|
||||
# Archived work records
|
||||
|
||||
> **Status:** Historical evidence index. These scratchpads record prior task execution and investigation; they are not active task state, current requirements, implementation contracts, or operational authority.
|
||||
|
||||
Ninety-four records moved byte-identically from migration quarantine on 2026-08-10 after a repository-wide consumer scan found no current path/name references and no coupled local Markdown links.
|
||||
|
||||
Because this collection is large, use repository search by issue, task, or topic rather than treating every file as current navigation. Validate all technical claims and commands against current source, tests, configuration, and safety policy.
|
||||
|
||||
## Retained in quarantine
|
||||
|
||||
Seventeen scratchpads were deliberately not moved because they are named by current control documents, tests/fixtures, retained mission/evidence records, or have a coupled KBN-101 report link. They must migrate with their owning workstream or consumer update.
|
||||
|
||||
## Boundaries
|
||||
|
||||
- Historical completion wording does not update `docs/TASKS.md` or mission authority.
|
||||
- Old commands are not approved runbooks.
|
||||
- Old security findings are not proof of current posture.
|
||||
- Draft designs are not current architecture.
|
||||
- Files remain byte-identical; this index supplies the lifecycle classification.
|
||||
@@ -129,7 +129,7 @@ systemctl --user restart mosaic-agent@<name>
|
||||
|
||||
Full recovery runbook and the three-layer #791 protection model (manifest
|
||||
ownership → pre-update snapshot/restore → regen): see
|
||||
[Upgrade Safety & Recovery](../ADMIN-GUIDE/operations/upgrade-safety-and-recovery.md).
|
||||
[Upgrade Safety & Recovery](./upgrade-safety-and-recovery.md).
|
||||
|
||||
## Release Preflight
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# Lease broker operations
|
||||
|
||||
Place the socket and state file in a dedicated directory with mode `0700`. Start the packaged daemon with:
|
||||
|
||||
```bash
|
||||
python3 "$MOSAIC_HOME/tools/lease-broker/daemon.py" \
|
||||
--socket /run/user/1000/mosaic-lease/broker.sock \
|
||||
--state /run/user/1000/mosaic-lease/state.json
|
||||
```
|
||||
|
||||
The broker refuses an existing parent directory whose mode is not exactly `0700`, an existing state file not at `0600`, corrupt/incompatible state, or an already-existing socket path. After bind it sets the socket to `0600`. It never silently unlinks a pre-existing socket. On normal termination it unlinks only the socket inode it created, so it does not remove a replacement path.
|
||||
|
||||
Before launching Claude, Claudex, or Pi, export the socket path; `mosaic` then runs the runtime through the packaged register-and-exec wrapper:
|
||||
|
||||
```bash
|
||||
export MOSAIC_LEASE_BROKER_SOCKET=/run/user/1000/mosaic-lease/broker.sock
|
||||
mosaic claude # or: mosaic claudex, mosaic yolo claudex, mosaic pi
|
||||
```
|
||||
|
||||
The wrapper obtains a broker-minted session ID, creates a private `generation-<session>.state` file beside the socket, and `exec`s the runtime without changing its PID/starttime anchor. The all-tools Claude `PreToolUse` hook and Pi `tool_call` handler inherit that identity and read the current generation from the file. Claudex retains its isolated proxy environment and config directory; Mosaic merges the mandatory all-tools and compaction-lifecycle hooks into that isolated `settings.json` before invoking the same wrapper. PRDY init/update, QA remediation, coord, orchestrator, and fleet launchers also converge on this boundary. Broker registration failure, unsafe isolated settings, unsafe generation state, or missing identity denies launch/tool execution fail-closed; broker timeout/unavailability and malformed replies also block tools.
|
||||
|
||||
Claude `PreCompact` and `SessionStart(compact)` hooks and Pi pre-/post-compaction handlers invoke `revoke-lease.py`. Pi `session_start` reload/new/resume/fork and Claude resume/clear advance the locked generation before revocation, so a replacement session inherits no lease even when PID/starttime stay unchanged. Do not invoke the revoker manually as a way to restore authority; it only removes authority. If a lifecycle hook reports failure, stop consequential work and repair broker/generation-state availability before re-verification.
|
||||
|
||||
Run the permanent launch inventory locally with:
|
||||
|
||||
```bash
|
||||
python3 packages/mosaic/framework/tools/lease-broker/check-runtime-launches.py --root .
|
||||
```
|
||||
|
||||
The same check runs in the Mosaic package test suite and therefore in root CI. Any direct Claude/Pi binary launch must be replaced with `launch-runtime.py`, `execLeaseGatedRuntime`, or the gated `mosaic` runtime command; do not add static allowlist exceptions.
|
||||
|
||||
Clients must complete the request boundary before waiting for a reply. After sending the single JSON object and its terminating newline, the client **MUST half-close the socket's write side** (`shutdown(SHUT_WR)` in POSIX clients; `socket.end()` in Node) and only then await the response. Merely calling `write()` and waiting is invalid: the broker waits for EOF to enforce the exact-one-frame contract and fails closed at its one-second deadline. Do not replace `end()` with `write()` in client helpers. A delayed second frame remains malformed and is rejected.
|
||||
|
||||
`mosaic_context_recover` is the only unverified mutator class. Its durable `mosaic-context-refresh` skill is a thin wrapper over `tools/lease-broker/recover-context.py`: `begin` has the broker rebuild the validated `B_payload`/`H_payload`, revoke first, and mint a new `PENDING_DELIVERY` receipt challenge; `complete` accepts neither receipt text nor a challenge argument. Claude maps only the exact direct recovery executable/validated arguments to this exempt tool identity; ordinary `Bash` remains gated. Pi exposes only the `mosaic_context_recover` custom tool; ordinary `bash` and all other tools remain gated. A normal-path receipt cannot be replayed through recovery because each retry begins a distinct recovery cycle and recovery completion cannot receive caller-presented evidence.
|
||||
|
||||
Production daemon startup creates a separate private observer socket unless a test-only `--test-observer-file` fixture is selected. Claude's Stop hook sends its exact latest assistant entry and Pi's `message_end` handler sends only finalized assistant content to that authenticated transport; the broker public socket never accepts message text. This is byte-build and private out-of-process harness wiring only: do not activate it against a live daemon, live socket, systemd service, tmux session, or model-output stream outside the controlled integration procedure.
|
||||
|
||||
Receipt honesty is load-bearing: absent, malformed, prefix-truncated, and observable adapter-mutated terminal receipts do not promote. A tail-only case is non-promoting only where the concrete terminal payload is malformed or observably incomplete. A tail-preserving middle drop is **not receipt-detectable**; it is the disclosed T-C injection-contract residual deferred to WI-7 server-side evidence. The receipt remains a T-A delivery/liveness prerequisite, never a safety, obedience, or residency proof. The framework skill is source-resident and bridge-projected on install/upgrade; do not hand-create a live runtime symlink.
|
||||
|
||||
After a runtime exits, its `generation-<session>.state` file may be removed only after verifying that no process for that broker-minted session remains; stale files carry no lease authority but should be retained during incident analysis. After a broker crash, preserve the protected state file and restart only after verifying that no broker owns the socket. Restart intentionally clears all volatile VERIFIED leases. A leftover socket requires an operator to verify the owning service is stopped and remove that exact socket deliberately. Corrupt, oversized, symlinked, or non-regular state fails closed; do not overwrite it. Preserve it for incident review and establish new state only through an explicit operational decision, which invalidates prior sessions and tokens.
|
||||
|
||||
## Security posture
|
||||
|
||||
Directory `0700` plus socket/state `0600` is built-in same-principal hardening only: it excludes other UIDs but does **not** stop the same UID from unlinking and counterfeiting the socket. It therefore does not close T-C same-UID replacement. WI-1 does not provide a distinct-principal boundary. A stronger distinct-principal deployment requires an external protected proxy, ACL, or service boundary that clients cannot unlink or rebind and that preserves the authenticated client identity required by the broker's `SO_PEERCRED` and ancestry checks. Server-side branch protection remains the irreducible backstop.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Mos Connector Lease Operations — M1
|
||||
|
||||
## Operational status
|
||||
|
||||
M1 installs the durable schema and gateway policy/adapter boundary. It does **not** activate a connector, expose a lease administration endpoint, or cut over a channel. The default gateway connector-lease policy is deny-all until a later work package supplies an authorized server-side policy and concrete adapter.
|
||||
|
||||
## Events to monitor
|
||||
|
||||
Use correlation IDs to follow `connector_lease_audit_log` events:
|
||||
|
||||
| Event | Meaning |
|
||||
| ---------- | --------------------------------------------------------------------- |
|
||||
| `acquire` | First holder inserted for an unused binding |
|
||||
| `renew` | Current holder heartbeat extended the TTL |
|
||||
| `takeover` | Authorized CAS replaced the holder and incremented epoch |
|
||||
| `release` | Current holder explicitly relinquished authority |
|
||||
| `expiry` | An expired current lease was observed |
|
||||
| `reject` | Policy, CAS, expiry, scope, or fencing validation denied an operation |
|
||||
|
||||
Audit data is metadata-only. Raw grant objects, connector payloads, scopes, tokens, approval references, and credentials must never be added to audit output.
|
||||
|
||||
## Incident checks
|
||||
|
||||
For suspected duplicate/stale connector effects:
|
||||
|
||||
1. Correlate the attempted operation with its `reject`, `takeover`, or `expiry` event.
|
||||
2. Compare the current row's connector ID, lease UUID, epoch, expiry, and release time with the adapter's normalized execution context.
|
||||
3. Treat an old epoch, old lease UUID, expired lease, or released lease as non-authoritative. Do not retry it as the old holder.
|
||||
4. Recovery uses the authorized takeover path with the observed expected epoch. Ordinary acquire is intentionally rejected for expired/released rows.
|
||||
5. If an external effect may already have happened, preserve evidence and do not assume lease fencing provides exactly-once replay safety.
|
||||
|
||||
## Migration and rollback safety
|
||||
|
||||
Migration `0016_salty_morlocks.sql` is additive: it creates two new tables and indexes without modifying existing authorization/session tables. Before rollout, normal database backup and migration verification still apply. Rolling application code back leaves unused additive tables in place; dropping tables is not part of automated rollback because it would destroy lease/audit evidence.
|
||||
|
||||
## Security constraints
|
||||
|
||||
- Tenant comes from authenticated gateway context, never a connector request field.
|
||||
- Logical agent, binding, connector, and scope identifiers use normalized constrained forms.
|
||||
- Takeover requires explicit gateway policy authorization and an expected epoch.
|
||||
- Default defense-in-depth TTL caps are 5 minutes for leases and 30 seconds for grants; policy may enforce stricter limits.
|
||||
- Validation and rejection audit complete before adapter side effects.
|
||||
- Existing authz and exact-action approval controls remain additional required gates; a valid connector lease does not bypass them.
|
||||
@@ -0,0 +1,147 @@
|
||||
# Upgrade Safety & Recovery
|
||||
|
||||
How Mosaic protects operator-owned configuration under `~/.config/mosaic` across
|
||||
framework upgrades, and how to recover if a projection is ever lost.
|
||||
|
||||
A framework upgrade runs `install.sh` in keep-mode (`MOSAIC_INSTALL_MODE=keep`,
|
||||
`MOSAIC_SYNC_ONLY=1`) to refresh framework-owned files in place. The incident
|
||||
this hardening addresses: an upgrade that silently overwrites or deletes a file
|
||||
the operator owns — credentials, personas, a roster, or a generated agent env —
|
||||
with no snapshot to fall back to.
|
||||
|
||||
Protection is layered. Each layer is independent; a later layer catches what an
|
||||
earlier one misses.
|
||||
|
||||
## Layer 1 — Manifest-owned sync (prevention)
|
||||
|
||||
The single source of truth for ownership is
|
||||
[`framework-manifest.txt`](../../packages/mosaic/framework/framework-manifest.txt).
|
||||
Both the bash installer and the TypeScript sync path resolve every path against
|
||||
this one file (parity is enforced by test), so they can never drift.
|
||||
|
||||
- Ownership is **allow-list, deny-wins**: a path is framework-owned only if a
|
||||
`[framework]` glob matches and no `[operator]` carve-out overrides it.
|
||||
- **Unknown paths default to operator** (fail-safe): a file the manifest never
|
||||
anticipated is treated as operator-owned and is never pruned.
|
||||
- Keep-mode does a non-deleting copy plus an explicit, manifest-scoped prune that
|
||||
only ever iterates framework globs — operator and unknown paths are
|
||||
structurally unreachable by the prune.
|
||||
|
||||
Result: a correct upgrade cannot touch operator config at all.
|
||||
|
||||
## Layer 2 — Durable pre-update snapshot + verify net (safety + rollback)
|
||||
|
||||
Before **any** mutation, the installer snapshots the operator-owned surface that
|
||||
exists into:
|
||||
|
||||
```
|
||||
${XDG_STATE_HOME:-~/.local/state}/mosaic/backups/pre-update-<UTC-timestamp>/
|
||||
```
|
||||
|
||||
- `0700` directories / `0600` files (`umask 077`, scoped and restored),
|
||||
outside `~/.config/mosaic` and outside any repo.
|
||||
- **Fail-open**: a snapshot failure warns but never aborts the upgrade it
|
||||
protects.
|
||||
- Retention is `MOSAIC_BACKUP_RETENTION` snapshots (default 5).
|
||||
|
||||
After the sync, a **verify net** compares each snapshot file against its target
|
||||
and restores (with a loud warning) any operator file the upgrade diverged or
|
||||
removed — a divergence means a manifest bug slipped through Layer 1.
|
||||
|
||||
Inspect and restore snapshots with the CLI:
|
||||
|
||||
```bash
|
||||
mosaic restore --list # dry-run: enumerate snapshots by timestamp
|
||||
mosaic restore --from <UTC-timestamp> # restore the operator surface from one snapshot
|
||||
mosaic restore --from <ts> --dry-run # preview a specific restore without writing
|
||||
```
|
||||
|
||||
`mosaic restore` reports **counts and relative paths only** — it never emits file
|
||||
contents, so a secret in `tools/_lib/credentials.json` is never echoed. Restores
|
||||
are confirmation-gated (`--yes` or `MOSAIC_ASSUME_YES`) and write each leaf
|
||||
atomically with `O_NOFOLLOW` (a symlink swapped in after the snapshot fails
|
||||
closed rather than following out of the managed tree).
|
||||
|
||||
## Layer 3 — Regeneration from roster SSOT (recovery)
|
||||
|
||||
Some operator files are **derived** and do not need a byte-for-byte snapshot to
|
||||
recover — they can be rebuilt from their source of truth. The fleet's per-agent
|
||||
generated env projections are the prime case:
|
||||
|
||||
- `~/.config/mosaic/fleet/agents/<name>.env.generated` is a deterministic
|
||||
projection of `~/.config/mosaic/fleet/roster.yaml`.
|
||||
- The launcher (`start-agent-session.sh`, invoked by
|
||||
`mosaic-agent@<name>.service`) sources that generated projection to establish
|
||||
each agent's identity, runtime, model, and working directory. If it is missing
|
||||
or wrong, the agent cannot launch with its intended identity.
|
||||
|
||||
`mosaic fleet regen` rebuilds those projections from the roster SSOT:
|
||||
|
||||
```bash
|
||||
mosaic fleet regen # dry-run (default): show what would be rebuilt
|
||||
mosaic fleet regen --json # same, machine-readable
|
||||
mosaic fleet regen --write # rebuild the projections on disk
|
||||
```
|
||||
|
||||
- **Dry-run by default.** Nothing is written until you pass `--write`.
|
||||
- **Deterministic and idempotent** — the projection is a pure function of the
|
||||
roster, so repeated `--write` runs produce byte-identical files.
|
||||
- **Projection-only. It never restarts an agent.** Recovery order forbids
|
||||
restart-before-verify; `regen` has no path to systemd lifecycle at all.
|
||||
- **It rebuilds only `<name>.env.generated`** — it never writes, relocates, or
|
||||
deletes the operator-owned `.env` / `.env.local` surface.
|
||||
- It **validates the roster the same way `reconcile` does** (persona resolution
|
||||
and protected-class tool-policy match), so a hand-edited or corrupt roster is
|
||||
rejected rather than projected, and a `--write` takes the shared reconcile
|
||||
lock so it cannot race a concurrent reconcile.
|
||||
- Output is **paths and counts only** — the rendered `KEY=value` body is never
|
||||
echoed.
|
||||
|
||||
`regen` uses the exact same roster→env mapping as `mosaic fleet reconcile`, so a
|
||||
recovered projection matches what a normal reconcile would have written.
|
||||
|
||||
## Recovery runbook — wiped `fleet/agents/*.env.generated`
|
||||
|
||||
If an upgrade (or a manual mistake) has left an agent without its generated
|
||||
projection, **do not restart the unit first** — a launch against a missing
|
||||
projection fails closed, and any stale state must be corrected before restart,
|
||||
not after.
|
||||
|
||||
1. **Prefer a snapshot restore if one exists** (byte-exact operator state):
|
||||
|
||||
```bash
|
||||
mosaic restore --list
|
||||
mosaic restore --from <UTC-timestamp>
|
||||
```
|
||||
|
||||
2. **Otherwise regenerate the derived projections from the roster SSOT:**
|
||||
|
||||
```bash
|
||||
mosaic fleet regen # confirm the plan (create vs rebuild per agent)
|
||||
mosaic fleet regen --write # rebuild fleet/agents/<name>.env.generated
|
||||
```
|
||||
|
||||
3. **Verify each unit will resolve the intended runtime/workdir _before_ any
|
||||
restart.** The unit sets **no** `EnvironmentFile=` — it launches from a minimal
|
||||
environment and `start-agent-session.sh` sources `.env.generated` itself, so
|
||||
verify the generated file directly and confirm the launcher path:
|
||||
|
||||
```bash
|
||||
# Confirm fleet/agents/<name>.env.generated exists and carries the intended
|
||||
# MOSAIC_AGENT_* values (name, runtime, model, workdir, socket).
|
||||
test -f ~/.config/mosaic/fleet/agents/<name>.env.generated
|
||||
# Confirm the unit launches the session script that reads it.
|
||||
systemctl --user cat mosaic-agent@<name> | grep ExecStart
|
||||
```
|
||||
|
||||
4. **Only then restart, one unit at a time:**
|
||||
|
||||
```bash
|
||||
systemctl --user restart mosaic-agent@<name>
|
||||
```
|
||||
|
||||
## See also
|
||||
|
||||
- Design: [`docs/design/791-upgrade-config-protection.md`](../design/791-upgrade-config-protection.md)
|
||||
- Fleet operations: [`docs/guides/fleet-local-canary.md`](./fleet-local-canary.md)
|
||||
- Ownership SSOT: [`packages/mosaic/framework/framework-manifest.txt`](../../packages/mosaic/framework/framework-manifest.txt)
|
||||
@@ -1,55 +0,0 @@
|
||||
# Documentation Catalog and Truth Audit Plan
|
||||
|
||||
**Task:** DOCS-IA-002
|
||||
**Internal reference:** `TASKS:DOCS-IA-002`
|
||||
**Goal:** Catalog the existing Mosaic Stack documentation, identify its intended destination in the new structure, and audit validity/truthfulness against repository evidence before moving or rewriting content.
|
||||
|
||||
## Scope
|
||||
|
||||
- Current root-level documentation and newly established structure files.
|
||||
- All Markdown and relevant YAML/API artifacts under `docs/_old_structure/`.
|
||||
- Repository references from source, tests, scripts, guides, and root README files.
|
||||
- Static truth checks for paths, commands, package names, environment variables, API artifacts, and explicit document status.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Do not move, delete, or rewrite documentation.
|
||||
- Do not decide product requirements that belong in `docs/PRD.md`.
|
||||
- Do not mark a claim true solely because it appears in a document.
|
||||
- Do not modify active `docs/TASKS.md` because it has a single-writer orchestrator policy.
|
||||
|
||||
## Parallel discovery lanes
|
||||
|
||||
1. **File catalog:** path, title, type, size, line count, current/archive location, last repository change.
|
||||
2. **Navigation audit:** Markdown and Obsidian links, target resolution, broken-link clusters, source references.
|
||||
3. **Code-surface audit:** package names, scripts, entry points, referenced docs, paths used by tests and source.
|
||||
4. **Truth triage:** compare current claims against executable code/config/tests and label evidence strength.
|
||||
|
||||
Parallel lanes produce findings only. The coordinator reconciles them into one report so truth labels remain consistent.
|
||||
|
||||
## Evidence statuses
|
||||
|
||||
- `verified`: directly supported by current source/config/tests or a reproducible command.
|
||||
- `partially-verified`: some claims are supported, but the page contains unverified or time-sensitive claims.
|
||||
- `contradicted`: current repository evidence conflicts with a material claim.
|
||||
- `stale`: formerly meaningful but no longer aligned with current paths, APIs, or state.
|
||||
- `historical`: intentionally retained record of past state; not a current instruction.
|
||||
- `draft`: normative proposal or requirement, not a statement of shipped behavior.
|
||||
- `unverified`: not yet checked or insufficient evidence exists.
|
||||
- `incomplete`: empty or structurally insufficient for its stated role.
|
||||
|
||||
## Deliverables
|
||||
|
||||
- `docs/reports/documentation/2026-08-10-docs-catalog-audit.md` — human-readable catalog, findings, evidence, and migration recommendations.
|
||||
- `docs/scratchpads/DOCS-IA-002-catalog-audit.md` — task progress and command evidence.
|
||||
|
||||
A machine-readable intermediate inventory may remain under `/tmp`; it is not canonical unless explicitly copied into the report.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- Every current documentation file and every archived documentation file is counted and assigned a preliminary disposition.
|
||||
- Broken internal links and repository references are enumerated with evidence.
|
||||
- Truth labels distinguish current behavior, normative intent, historical evidence, and unresolved claims.
|
||||
- High-risk contradictions and source/test dependencies are called out before any migration.
|
||||
- The report recommends migration order and identifies pages requiring human/product-owner validation.
|
||||
- No existing documentation or unrelated working-tree state is modified.
|
||||
@@ -1,182 +0,0 @@
|
||||
# Documentation Information Architecture Design
|
||||
|
||||
**Status:** Approved
|
||||
**Date:** 2026-08-10
|
||||
**Scope:** Establish the canonical structure and authoring rules for `docs/` before migrating or rewriting existing documentation.
|
||||
|
||||
## Goal
|
||||
|
||||
Create a clean, human-readable, Obsidian-compatible documentation system for Mosaic Stack. The system must make the relationships between requirements, architecture, guides, API contracts, operational procedures, evidence, and work tracking visible without duplicating canonical content.
|
||||
|
||||
## Decision
|
||||
|
||||
Use a single root-level documentation atlas in `docs/README.md`, organized around audience-specific guide books and dedicated artifact directories. Retire `docs/mosaic-stack/` as a content boundary; it adds no useful ownership distinction once the documentation system has explicit root guides and cross-links.
|
||||
|
||||
The target structure is:
|
||||
|
||||
```text
|
||||
docs/
|
||||
├── README.md
|
||||
├── PRD.md
|
||||
├── TASKS.md
|
||||
├── SITEMAP.md
|
||||
│
|
||||
├── USER-GUIDE/
|
||||
│ ├── README.md
|
||||
│ ├── getting-started/
|
||||
│ ├── concepts/
|
||||
│ ├── workflows/
|
||||
│ └── troubleshooting/
|
||||
│
|
||||
├── ADMIN-GUIDE/
|
||||
│ ├── README.md
|
||||
│ ├── installation/
|
||||
│ ├── configuration/
|
||||
│ ├── deployment/
|
||||
│ ├── operations/
|
||||
│ ├── security/
|
||||
│ └── recovery/
|
||||
│
|
||||
├── DEVELOPER-GUIDE/
|
||||
│ ├── README.md
|
||||
│ ├── architecture/
|
||||
│ │ ├── README.md
|
||||
│ │ ├── system-overview.md
|
||||
│ │ ├── component-map.md
|
||||
│ │ ├── data-flow.md
|
||||
│ │ ├── security-model.md
|
||||
│ │ ├── decisions/
|
||||
│ │ └── rfcs/
|
||||
│ ├── packages/
|
||||
│ ├── local-development/
|
||||
│ ├── testing/
|
||||
│ ├── contributing/
|
||||
│ └── integrations/
|
||||
│
|
||||
├── API/
|
||||
│ ├── README.md
|
||||
│ ├── OPENAPI.yaml
|
||||
│ └── ENDPOINTS.md
|
||||
│
|
||||
├── assets/
|
||||
├── reports/
|
||||
│ ├── code-review/
|
||||
│ ├── documentation/
|
||||
│ ├── qa/
|
||||
│ ├── security/
|
||||
│ └── deferred/
|
||||
├── tasks/
|
||||
├── plans/
|
||||
├── scratchpads/
|
||||
├── releases/
|
||||
├── archive/
|
||||
└── _old_structure/ # temporary migration quarantine; read-only
|
||||
```
|
||||
|
||||
`docs/plans/` is a workflow directory for approved design and implementation plans. It is not a substitute for the canonical requirements document, active task ledger, or guide books.
|
||||
|
||||
## Information architecture
|
||||
|
||||
### Root control documents
|
||||
|
||||
- `docs/README.md` is the documentation contract, placement guide, and top-level entry point.
|
||||
- `docs/PRD.md` is the canonical product and requirements source. Requirements must not be silently redefined in guides or reports.
|
||||
- `docs/TASKS.md` is the active orchestrator rollup. Its single-writer policy remains authoritative.
|
||||
- `docs/SITEMAP.md` is the complete human navigation index. It must be updated when canonical pages are added, moved, renamed, or retired.
|
||||
|
||||
### Audience books
|
||||
|
||||
- `USER-GUIDE/` contains end-user workflows, user-visible behavior, concepts needed to operate the product, and user troubleshooting.
|
||||
- `ADMIN-GUIDE/` contains installation, configuration, deployment, operations, security controls, recovery, and incident procedures.
|
||||
- `DEVELOPER-GUIDE/` contains architecture, package/component documentation, local development, testing, contribution rules, and integration authoring.
|
||||
- `API/` contains the machine-readable OpenAPI contract and its human-readable endpoint index.
|
||||
|
||||
Audience books are task-oriented. They link to canonical architecture, requirements, API, and operational pages rather than copying those pages.
|
||||
|
||||
### Artifact directories
|
||||
|
||||
- `assets/` contains diagrams and documentation media referenced by canonical pages.
|
||||
- `reports/` contains evidence and findings. Reports are informative and do not override the PRD or normative contracts.
|
||||
- `tasks/` contains archived task snapshots and orchestrator learnings. Active orchestration remains in root `TASKS.md`.
|
||||
- `plans/` contains approved design and implementation plans.
|
||||
- `scratchpads/` contains active, task-specific working notes and verification evidence. Scratchpads are not product documentation.
|
||||
- `releases/` contains release notes and release-specific migration or compatibility notes.
|
||||
- `archive/` contains superseded but intentionally retained documentation. Archived pages must state their replacement or reason for retention.
|
||||
- `_old_structure/` is a temporary migration quarantine. It is read-only, is not indexed as current documentation, and is not an authoring destination.
|
||||
|
||||
## Placement rules
|
||||
|
||||
| Content | Required location | Do not place it in |
|
||||
| ----------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------- |
|
||||
| Product requirements and acceptance criteria | `docs/PRD.md` or an explicitly scoped PRD under a guide/workstream | A scratchpad, report, or README-only note |
|
||||
| Active task status | `docs/TASKS.md` | A guide page or personal scratchpad |
|
||||
| User workflow | `docs/USER-GUIDE/<chapter>/` | The docs root |
|
||||
| Installation, deployment, or recovery procedure | `docs/ADMIN-GUIDE/<chapter>/` | `README.md` or a report |
|
||||
| Architecture, component, package, ADR, or RFC content | `docs/DEVELOPER-GUIDE/architecture/` or its relevant developer chapter | `docs/mosaic-stack/` or the docs root |
|
||||
| API contract | `docs/API/OPENAPI.yaml` and `docs/API/ENDPOINTS.md` | A guide-only description |
|
||||
| Documentation navigation | `docs/SITEMAP.md` | A duplicated ad-hoc index |
|
||||
| Design or implementation plan | `docs/plans/` | `docs/scratchpads/` |
|
||||
| Active task working notes | `docs/scratchpads/<task-id>-<slug>.md` | The docs root or a canonical guide |
|
||||
| Review, QA, audit, security, or deferral evidence | `docs/reports/<category>/` | A canonical guide page |
|
||||
| Archived task snapshot | `docs/tasks/` | Root `TASKS.md` unless it is active |
|
||||
| Release notes | `docs/releases/` | The docs root |
|
||||
| Diagram or image | `docs/assets/` or an owning chapter asset directory | An external personal path |
|
||||
| Superseded documentation | `docs/archive/` | `_old_structure/` after migration completes |
|
||||
|
||||
When a page appears to fit multiple locations, classify it by its primary reader and purpose, then link it from the other relevant indexes. Do not create copies to satisfy multiple audiences.
|
||||
|
||||
## Page conventions
|
||||
|
||||
Every canonical Markdown page should:
|
||||
|
||||
1. Cover one concern or workflow.
|
||||
2. Use a descriptive, lowercase kebab-case filename, except for established root control files and required API filenames.
|
||||
3. Begin with a clear title and a short purpose statement.
|
||||
4. Declare status and audience when the page is more than a simple index.
|
||||
5. Identify prerequisites, source-of-truth dependencies, and related pages.
|
||||
6. State whether examples and commands are current, illustrative, or held/non-operative.
|
||||
7. Include an owner or maintenance responsibility when the content is operationally sensitive.
|
||||
|
||||
Recommended front matter for canonical pages:
|
||||
|
||||
```yaml
|
||||
---
|
||||
title: Human-readable page title
|
||||
type: guide
|
||||
audience: developer
|
||||
status: current
|
||||
---
|
||||
```
|
||||
|
||||
Allowed `type` values include `guide`, `concept`, `reference`, `decision`, `rfc`, and `runbook`. Allowed `audience` values are `user`, `admin`, `developer`, and `all`. Allowed `status` values are `current`, `draft`, `deprecated`, and `historical`.
|
||||
|
||||
## Obsidian and link conventions
|
||||
|
||||
- Use Obsidian wikilinks for relationship-oriented internal references, for example `[[DEVELOPER-GUIDE/architecture/component-map|Component map]]`.
|
||||
- Use normal relative Markdown links in `SITEMAP.md` and book `README.md` indexes so links render on Git hosting platforms. Obsidian can resolve these links too.
|
||||
- Use `Related`, `Depends on`, and `Referenced by` sections when a page participates in a meaningful documentation relationship.
|
||||
- Link to stable page paths, not transient line numbers or branch URLs.
|
||||
- Omit `.md` in wikilinks. Include an alias when the file path is not a readable label.
|
||||
- Use standard Markdown links for external URLs, source files, commands, and API paths.
|
||||
- Do not rely on a link to `_old_structure/` as a current navigation path. Historical references must explain why the archived page is retained and point to its replacement.
|
||||
|
||||
## Migration rules
|
||||
|
||||
This design phase does not move or rewrite content. During later migration:
|
||||
|
||||
1. Inventory current pages and classify each by audience, purpose, status, and source-of-truth role.
|
||||
2. Move canonical content into the target tree without changing meaning unless the migration task explicitly includes a rewrite.
|
||||
3. Update all repository links, source comments, tests, and `SITEMAP.md` in the same logical change.
|
||||
4. Preserve historical evidence in `reports/`, `tasks/`, `releases/`, or `archive/` rather than mixing it into current guides.
|
||||
5. Treat `_old_structure/` as read-only during migration. It may be removed only after all required links and source references are resolved.
|
||||
6. Do not add new content to `docs/mosaic-stack/`; the empty directory is retired by this design.
|
||||
7. For documents referenced by executable tests or source code, update those references deliberately and verify them before deleting the old path.
|
||||
|
||||
## Acceptance criteria
|
||||
|
||||
- `docs/README.md` defines the complete target tree and placement rules.
|
||||
- The target tree has no `docs/mosaic-stack/` content boundary.
|
||||
- Agents can determine where to put product docs, plans, task notes, reports, scratchpads, releases, and archives without guessing.
|
||||
- The rules support both Obsidian graph navigation and Git-hosted Markdown navigation.
|
||||
- The design distinguishes normative sources from evidence and working notes.
|
||||
- Migration can proceed incrementally without treating `_old_structure/` as current documentation.
|
||||
@@ -1,135 +0,0 @@
|
||||
# Documentation Structure README Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Replace the starter `docs/README.md` with the normative documentation structure, placement rules, source-of-truth policy, and Obsidian-compatible navigation conventions approved for Mosaic Stack.
|
||||
|
||||
**Architecture:** Keep `docs/README.md` as the root documentation atlas and authoring contract. Use audience books for current user, administrator, and developer content; keep API contracts and operational artifacts in dedicated directories; retain `_old_structure/` as a read-only migration quarantine. Do not move or rewrite existing documentation in this slice.
|
||||
|
||||
**Tech Stack:** Markdown, YAML front matter examples, Obsidian wikilinks, relative Markdown links, Prettier.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Write the documentation structure contract
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `docs/README.md`
|
||||
- Reference: `docs/plans/2026-08-10-docs-information-architecture-design.md`
|
||||
|
||||
**Step 1: Confirm the approved design and current transition constraints**
|
||||
|
||||
Verify that the README preserves these decisions:
|
||||
|
||||
- `docs/mosaic-stack/` is not a target content directory.
|
||||
- `docs/README.md` is the documentation atlas and placement contract.
|
||||
- Existing files are not moved or rewritten yet.
|
||||
- `_old_structure/` is read-only migration quarantine.
|
||||
- Root control files, audience books, API, reports, tasks, plans, scratchpads, releases, archive, and assets have distinct responsibilities.
|
||||
|
||||
**Step 2: Replace the starter README**
|
||||
|
||||
Write `docs/README.md` with these sections:
|
||||
|
||||
1. Purpose and scope.
|
||||
2. Reader entry points.
|
||||
3. Complete target directory tree, including the optional `.obsidian/` vault configuration boundary and the workflow-only `plans/` directory.
|
||||
4. Root control document responsibilities.
|
||||
5. Guide book responsibilities and chapter rules.
|
||||
6. Artifact directory responsibilities.
|
||||
7. Placement matrix for agents.
|
||||
8. Source-of-truth and precedence rules.
|
||||
9. Page naming and front matter conventions.
|
||||
10. Obsidian wikilink and Git-hosted Markdown link conventions.
|
||||
11. Authoring workflow for new or changed documentation.
|
||||
12. Migration rules for `_old_structure/`, legacy root files, and repository references.
|
||||
13. Current transitional exceptions and explicit non-goals.
|
||||
|
||||
Use future target paths as a blueprint, but clearly label directories that are not populated yet so readers do not mistake the blueprint for completed migration.
|
||||
|
||||
**Step 3: Preserve the existing Obsidian configuration boundary**
|
||||
|
||||
Document `.obsidian/` as optional vault metadata only. Do not place Markdown content, scratchpads, reports, or source-of-truth files under it, and do not modify its existing files in this task.
|
||||
|
||||
**Step 4: Keep the README portable**
|
||||
|
||||
Use ordinary relative Markdown links for indexes and Git-hosted navigation. Use Obsidian wikilinks for graph-oriented relationships such as `Related`, `Depends on`, and `Referenced by`. Do not make a current navigation path depend solely on a Git-host-incompatible wikilink.
|
||||
|
||||
**Step 5: Review the resulting document**
|
||||
|
||||
Check that an agent can answer all of these without inspecting another file:
|
||||
|
||||
- Where does a user guide go?
|
||||
- Where does an admin runbook go?
|
||||
- Where does architecture or an RFC go?
|
||||
- Where does an API contract go?
|
||||
- Where does an active scratchpad go?
|
||||
- Where does a review or QA report go?
|
||||
- Where does an approved design or implementation plan go?
|
||||
- Which files are normative, working notes, evidence, or historical?
|
||||
- What may be added directly under `docs/`?
|
||||
|
||||
**Step 6: Commit only the README**
|
||||
|
||||
Because `docs/GETTING_STARTED.md` is an unrelated pre-staged deletion, stage and commit only `docs/README.md`:
|
||||
|
||||
```bash
|
||||
git add docs/README.md
|
||||
git commit --only docs/README.md -m "docs: codify documentation structure"
|
||||
```
|
||||
|
||||
Expected: the commit contains only the README change; the existing staged deletion and orchestrator state remain outside the commit.
|
||||
|
||||
### Task 2: Verify the README-only change
|
||||
|
||||
**Files:**
|
||||
|
||||
- Verify: `docs/README.md`
|
||||
|
||||
**Step 1: Run Markdown formatting validation**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
pnpm exec prettier --check docs/README.md
|
||||
```
|
||||
|
||||
Expected: Prettier reports the file is formatted.
|
||||
|
||||
**Step 2: Run whitespace validation**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git diff --check HEAD^ -- docs/README.md
|
||||
```
|
||||
|
||||
Expected: no whitespace errors.
|
||||
|
||||
**Step 3: Validate required structural anchors**
|
||||
|
||||
Run a focused search or script confirming the README names:
|
||||
|
||||
- `PRD.md`, `TASKS.md`, and `SITEMAP.md`;
|
||||
- `USER-GUIDE/`, `ADMIN-GUIDE/`, `DEVELOPER-GUIDE/`, and `API/`;
|
||||
- `reports/`, `tasks/`, `plans/`, `scratchpads/`, `releases/`, `archive/`, and `assets/`;
|
||||
- `_old_structure/` as read-only quarantine;
|
||||
- `docs/mosaic-stack/` as retired/non-authoring;
|
||||
- Obsidian wikilinks and Git-compatible Markdown links.
|
||||
|
||||
Expected: all anchors are present and no section instructs agents to create content under `docs/mosaic-stack/`.
|
||||
|
||||
**Step 4: Confirm scope isolation**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git show --stat --oneline HEAD
|
||||
```
|
||||
|
||||
Expected: the new commit contains only `docs/README.md`; pre-existing `.mosaic/orchestrator/*`, `docs/GETTING_STARTED.md`, and `docs/.obsidian/` states remain untouched.
|
||||
|
||||
**Step 5: Record verification evidence**
|
||||
|
||||
Update the task scratchpad at `docs/scratchpads/DOCS-IA-001.md` with commands, results, known transitional gaps, and the next migration slice. Do not modify active `docs/TASKS.md`; its single-writer policy belongs to the orchestrator.
|
||||
@@ -1,17 +0,0 @@
|
||||
# Documentation Plans
|
||||
|
||||
> **Status:** Current artifact index. Plans record approved intent and execution approach; they are not current product behavior or operational authority.
|
||||
|
||||
## Documentation migration plans
|
||||
|
||||
- [Information architecture design](2026-08-10-docs-information-architecture-design.md) — approved audience books, artifact boundaries, source-of-truth rules, and migration model.
|
||||
- [Documentation structure README implementation](2026-08-10-docs-structure-readme.md) — completed implementation plan for the documentation contract and atlas.
|
||||
- [Documentation catalog and truth audit](2026-08-10-docs-catalog-audit.md) — audit method, evidence statuses, deliverables, and acceptance criteria.
|
||||
|
||||
After a plan is delivered, update the canonical guide, contract, decision, or index. Do not cite a plan as proof that intended behavior shipped.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[SITEMAP|Documentation sitemap]]
|
||||
- [[scratchpads/README|Documentation scratchpads]]
|
||||
@@ -1,51 +0,0 @@
|
||||
# Documentation Reports
|
||||
|
||||
> **Status:** Current evidence index. Reports record reviews, tests, audits, and deferred findings; they are not requirements or operational instructions by themselves.
|
||||
|
||||
Use the canonical guide, API contract, source, and tests to determine current behavior. A report retains the scope and verdict of its original review unless a later report explicitly supersedes it.
|
||||
|
||||
## Documentation evidence
|
||||
|
||||
- [Documentation catalog and truth audit](documentation/2026-08-10-docs-catalog-audit.md) — migration inventory and static truth assessment.
|
||||
- [Fleet documentation IA closure](documentation/758-fleet-config-ia-closure.md) — active Fleet documentation acceptance evidence; the executable book remains at `docs/fleet/`.
|
||||
- [Fleet documentation deferrals](deferred/758-fleet-config-deferrals.md) — explicit holds and deferred live-action boundaries.
|
||||
- [Issue #756 documentation checklist](documentation/756-discord-plugin-checklist.md) — historical completion checklist for the official Discord plugin workstream.
|
||||
- [Framework consistency audit — 2026-02-17](documentation/AUDIT-2026-02-17-framework-consistency.md) — historical framework consistency and remediation snapshot.
|
||||
- [Compaction-refresh #830 checklist](compaction-refresh/830-documentation-checklist.md) — historical incomplete-at-snapshot documentation checklist.
|
||||
|
||||
## Code-review evidence
|
||||
|
||||
- [Issue #756 independent code review](code-review/756-code-review.md) — historical exact-scope review of the official Discord plugin workstream.
|
||||
- [Gateway security-hardening code review — 2026-03-13](code-review/gateway-security-20260313.md) — historical no-blocker review snapshot.
|
||||
|
||||
## Security evidence
|
||||
|
||||
- [Issue #756 security review](security/756-security-review.md) — historical security review of Discord ingress, authorization, routing, and residual risks.
|
||||
|
||||
## QA evidence
|
||||
|
||||
- [P8-003 performance optimization report](qa/p8-003-performance-optimization.md) — historical implementation evidence; not a current SLO or production benchmark.
|
||||
- [Gateway security-hardening QA report — 2026-03-13](qa/gateway-security-20260313.md) — historical test report with its original live-smoke-test limitation.
|
||||
|
||||
## Native Kanban/SOT evidence
|
||||
|
||||
These reports preserve the review sequence for issue #751. Their GO verdicts apply only to the reviewed historical scope and do not decide current Kanban authority or authorize held KBN-101 database work.
|
||||
|
||||
- [Initial independent NO-GO](native-kanban-sot/canon-initial-review-no-go.md) — original blocking review.
|
||||
- [Independent re-review GO](native-kanban-sot/canon-final-rereview-go.md) — follow-up closure review.
|
||||
- [Ultron final GO](native-kanban-sot/ultron-final-go.md) — historical final-gate record.
|
||||
- [KBN-101 security/architecture review](native-kanban-sot/kbn-101-contract-security-review-82ce325.md) — active review evidence coupled to the held KBN-101 authority surface.
|
||||
|
||||
## Retention rules
|
||||
|
||||
- Preserve report wording and verdicts when migrating historical evidence.
|
||||
- Keep the reviewed commit, issue, scope, and date visible when present.
|
||||
- Do not treat an old approval as approval of later code.
|
||||
- Link each tracked report from this index or an explicitly scoped child index.
|
||||
- Put current operator procedures in the administrator guide, not in reports.
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation contract]]
|
||||
- [[SITEMAP|Documentation sitemap]]
|
||||
- [[archive/README|Documentation archive]]
|
||||
@@ -1,527 +0,0 @@
|
||||
# Mosaic Stack Documentation Catalog and Truth Audit
|
||||
|
||||
> **Status:** First-pass static audit — 2026-08-10
|
||||
> **Task:** `DOCS-IA-002` / `TASKS:DOCS-IA-002`
|
||||
> **Scope:** Catalog and evidence triage only. No existing documentation was moved, deleted, or rewritten by this audit. The baseline catalog snapshot predates the DOCS-IA-002 plan, scratchpad, and report; those artifacts are listed separately and excluded from baseline counts to avoid self-referential metrics.
|
||||
|
||||
## Executive summary
|
||||
|
||||
- **283 baseline documentation artifacts** are cataloged: 11 current root files, 269 files under `docs/_old_structure/`, two prior plans, and one prior scratchpad. The three DOCS-IA-002 artifacts are listed separately.
|
||||
- At the audit baseline, `.gitignore` ignored `docs/reports/`, conflicting with the documentation contract. The migration subsequently removed that blanket rule so canonical reports can be tracked normally.
|
||||
- The current navigation surface contains **97 internal links, 83 legacy/unresolved links**, plus 2 intentional future blueprint wikilinks in the new `docs/README.md`.
|
||||
- The historical archive contains **122 links, 12 unresolved links**. These do not represent current navigation, but they matter if pages are promoted again.
|
||||
- The current broken-link problem is concentrated in `docs/SITEMAP.md` (66), `docs/MISSION-MANIFEST.md` (7), `docs/TASKS.md` (7), and `docs/PRD.md` (3).
|
||||
- Static code inspection found **31 source/test/framework files** that still reference legacy documentation roots such as `docs/fleet/`, `docs/federation/`, or `docs/architecture/`. These paths cannot be removed until their consumers are migrated or deliberately updated.
|
||||
- The workspace currently contains **26 package manifests**, 12 root scripts, and 110 package scripts. This is sufficient evidence to validate package/path claims statically, but not to prove deployed behavior.
|
||||
|
||||
### High-confidence findings
|
||||
|
||||
1. `docs/QUICKSTART.md` is empty and cannot serve as a quickstart.
|
||||
2. `docs/SITEMAP.md` is structurally stale after the archive move; it is not a reliable current navigation map.
|
||||
3. `docs/PRD-TUI_Improvements.md` and `docs/TASKS-TUI_Improvements.md` describe a missing `packages/cli` and missing historical worktree. Current TUI code is under `packages/mosaic`.
|
||||
4. `docs/SSO-PROVIDERS.md` has a verified provider environment-variable core, but its `NEXT_PUBLIC_*_ENABLED` web-flow claim does not match current dynamic provider discovery through `/api/sso/providers`; Keycloak SAML fallback is also absent from the guide.
|
||||
5. `docs/openapi-tess.yaml` parses as OpenAPI 3.1.0 with 17 paths and is useful as a Tess-scoped contract, but it is in a legacy root location and is not a complete gateway API contract.
|
||||
6. `docs/PRD.md` is explicitly draft and normative. Its acceptance criteria must not be presented as shipped capabilities; several of its path references are broken because supporting artifacts are archived.
|
||||
|
||||
## Audit status model
|
||||
|
||||
| Status | Meaning |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------- |
|
||||
| `verified` | Directly supported by current source, configuration, tests, or a reproducible static command. |
|
||||
| `partially-verified` | Some claims are supported, but the page includes unverified, time-sensitive, or environment-dependent claims. |
|
||||
| `contradicted` | Current repository evidence conflicts with a material claim or referenced path. |
|
||||
| `stale` | Formerly meaningful, but no longer aligned with current paths or tracked state. |
|
||||
| `historical` | Retained record of past state; not current operator or developer guidance. |
|
||||
| `draft` | Normative proposal or requirement; not a statement of shipped behavior. |
|
||||
| `unverified` | No sufficient evidence was collected in this first pass. |
|
||||
| `incomplete` | Empty or structurally insufficient for its stated role. |
|
||||
|
||||
A document can have two labels, such as `partially-verified/contradicted`, when one section is supported and another section is materially wrong. Archived files are labeled `historical/unverified`: archival status is known, but historical claim accuracy has not been proven.
|
||||
|
||||
## Current-document truth triage
|
||||
|
||||
| Document | Preliminary status | Role | Evidence and truth notes | Candidate destination |
|
||||
| -------------------------------- | ------------------------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
| `docs/MISSION-MANIFEST.md` | `stale` | MVP mission rollup | Last updated 2026-07-14; seven current-path links are broken and its active-workstream claims were not revalidated. | `tasks/ or archive/missions/` |
|
||||
| `docs/PERFORMANCE.md` | `partially-verified` | historical performance report | All seven named implementation files exist and key configuration/index markers are present; target metrics and production impact are not proven by this static audit. | `reports/qa/` |
|
||||
| `docs/PRD-TUI_Improvements.md` | `contradicted/stale` | branch-specific TUI PRD | It names missing `packages/cli` and an absent historical worktree; current TUI code is under `packages/mosaic`. | `archive/ or plans/` |
|
||||
| `docs/PRD.md` | `draft` | normative product requirements | Explicitly marked draft; three current links point to archived paths. Requirements express intent and acceptance criteria, not shipped behavior. | `PRD.md; split supporting contracts later` |
|
||||
| `docs/QUICKSTART.md` | `incomplete` | quickstart placeholder | Empty file: 0 bytes and 0 lines. | `USER-GUIDE/getting-started/quickstart.md` |
|
||||
| `docs/README.md` | `current/verified` | documentation structure contract | Structure, placement, source-of-truth, migration, and link rules were checked in this task; two future blueprint wikilinks are intentionally unresolved. | `README.md` |
|
||||
| `docs/SITEMAP.md` | `stale/contradicted` | navigation index | 66 current links resolve only against removed pre-archive paths; it must be regenerated after the canonical scaffold and migration map are approved. | `SITEMAP.md` |
|
||||
| `docs/SSO-PROVIDERS.md` | `partially-verified/contradicted` | SSO operator guide | Required provider environment names and partial-config behavior match `packages/auth`; documented `NEXT_PUBLIC_*_ENABLED` flags are not read by current web code, which discovers providers through `/api/sso/providers`. | `ADMIN-GUIDE/security/sso-providers.md` |
|
||||
| `docs/TASKS-TUI_Improvements.md` | `stale/historical` | branch-specific TUI task ledger | References an absent worktree and `packages/cli`; Wave 1/2 status and commit claims were not independently reverified against current code. | `tasks/ or archive/` |
|
||||
| `docs/TASKS.md` | `active/stale-links` | MVP orchestrator rollup | Active rollup with seven broken workstream links. Status is orchestrator-owned and was not changed by this audit. | `TASKS.md until orchestrator archives it` |
|
||||
| `docs/openapi-tess.yaml` | `partially-verified/legacy-location` | Tess-scoped OpenAPI contract | PyYAML parses OpenAPI 3.1.0 with 17 paths. It covers Tess interaction, Mos coordination, and memory routes, but is not at `docs/API/` and is not a complete gateway contract. | `API/ (scoped Tess contract or consolidated OPENAPI.yaml)` |
|
||||
|
||||
### DOCS-IA-002 audit artifacts
|
||||
|
||||
- `docs/plans/2026-08-10-docs-catalog-audit.md` — approved audit method and evidence statuses.
|
||||
- `docs/scratchpads/DOCS-IA-002-catalog-audit.md` — active audit progress and command log.
|
||||
- `docs/reports/documentation/2026-08-10-docs-catalog-audit.md` — this human-readable report; it required force-add at the audit baseline, before the blanket report ignore rule was removed.
|
||||
- These artifacts are current working/evidence documentation and must not be mistaken for product requirements or shipped behavior.
|
||||
|
||||
## Archived catalog by category
|
||||
|
||||
All files below were moved unchanged by commit `cd4409a` on 2026-08-10. Category counts are definitive for this checkout; truth claims remain unverified until a page is selected for migration.
|
||||
|
||||
| Archived category | Files | Bytes | Preliminary destination | Default disposition |
|
||||
| --------------------- | ----: | ------: | ----------------------------------------------------------------- | -------------------------------------------------- |
|
||||
| `architecture/` | 7 | 84,248 | `DEVELOPER-GUIDE/architecture/` | `historical/unverified`; classify before promotion |
|
||||
| `archive/` | 11 | 108,472 | `archive/` | `historical/unverified`; classify before promotion |
|
||||
| `audits/` | 1 | 5,037 | `reports/documentation/ or reports/security/` | `historical/unverified`; classify before promotion |
|
||||
| `briefs/` | 1 | 10,589 | `plans/ or archive/` | `historical/unverified`; classify before promotion |
|
||||
| `compaction-refresh/` | 2 | 21,484 | `DEVELOPER-GUIDE/architecture/ or reports/qa/` | `historical/unverified`; classify before promotion |
|
||||
| `deploy/` | 2 | 10,881 | `ADMIN-GUIDE/deployment/` | `historical/unverified`; classify before promotion |
|
||||
| `design/` | 4 | 45,773 | `DEVELOPER-GUIDE/architecture/decisions/ or plans/` | `historical/unverified`; classify before promotion |
|
||||
| `federation/` | 6 | 95,408 | `ADMIN-GUIDE/deployment/ and DEVELOPER-GUIDE/architecture/` | `historical/unverified`; classify before promotion |
|
||||
| `fleet/` | 38 | 214,726 | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` | `historical/unverified`; classify before promotion |
|
||||
| `guides/` | 9 | 94,257 | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` | `historical/unverified`; classify before promotion |
|
||||
| `mission-control/` | 4 | 33,605 | `tasks/ or archive/` | `historical/unverified`; classify before promotion |
|
||||
| `native-kanban-sot/` | 13 | 659,105 | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` | `historical/unverified`; classify before promotion |
|
||||
| `plans/` | 12 | 298,514 | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` | `historical/unverified`; classify before promotion |
|
||||
| `remediation/` | 8 | 218,485 | `reports/deferred/ or tasks/` | `historical/unverified`; classify before promotion |
|
||||
| `reports/` | 12 | 79,398 | `reports/<category>/` | `historical/unverified`; classify before promotion |
|
||||
| `requirements/` | 1 | 27,315 | `PRD.md or DEVELOPER-GUIDE/architecture/requirements/` | `historical/unverified`; classify before promotion |
|
||||
| `reviews/` | 1 | 51,000 | `reports/code-review/` | `historical/unverified`; classify before promotion |
|
||||
| `rfcs/` | 2 | 114,255 | `DEVELOPER-GUIDE/architecture/rfcs/` | `historical/unverified`; classify before promotion |
|
||||
| `scratchpads/` | 111 | 638,974 | `archive/ or tasks/ after retention review` | `historical/unverified`; classify before promotion |
|
||||
| `tasks/` | 4 | 20,803 | `tasks/` | `historical/unverified`; classify before promotion |
|
||||
| `tess/` | 20 | 645,134 | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` | `historical/unverified`; classify before promotion |
|
||||
|
||||
### Category interpretation
|
||||
|
||||
- `architecture/`, `design/`, `requirements/`, and `rfcs/` are likely developer architecture material, but each page must be checked for supersession, normative authority, and code alignment.
|
||||
- `fleet/`, `federation/`, and `tess/` are mixed audiences. They must be split across user, admin, developer, API, reports, and task destinations rather than moved as whole directories.
|
||||
- `guides/` contains mixed audience material and cannot be mapped by directory name alone.
|
||||
- `scratchpads/`, `remediation/`, `reports/`, `reviews/`, and `tasks/` are evidence/workflow artifacts. They should not be promoted into current guides without extracting and re-verifying the current facts.
|
||||
- `archive/` is already historical by intent and should remain separate from the new migration target unless a specific page is needed for provenance.
|
||||
|
||||
## Baseline file-level catalog
|
||||
|
||||
The following table assigns every file in the baseline snapshot a preliminary status, role, evidence posture, and candidate destination. The DOCS-IA-002 plan, scratchpad, and report are listed in the audit-artifacts section above. These are triage labels, not final migration approvals.
|
||||
|
||||
| Path | Title | Status | Role | Evidence posture | Candidate destination |
|
||||
| ------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `docs/MISSION-MANIFEST.md` | Mission Manifest — MVP | `stale` | MVP mission rollup | Last updated 2026-07-14; seven current-path links are broken and its active-workstream claims were not revalidated. | `tasks/ or archive/missions/` |
|
||||
| `docs/PERFORMANCE.md` | Performance Optimization — P8-003 | `partially-verified` | historical performance report | All seven named implementation files exist and key configuration/index markers are present; target metrics and production impact are not proven by this static audit. | `reports/qa/` |
|
||||
| `docs/PRD-TUI_Improvements.md` | PRD: TUI Improvements — Phase 7 | `contradicted/stale` | branch-specific TUI PRD | It names missing `packages/cli` and an absent historical worktree; current TUI code is under `packages/mosaic`. | `archive/ or plans/` |
|
||||
| `docs/PRD.md` | PRD: Mosaic Stack v0.1.0 | `draft` | normative product requirements | Explicitly marked draft; three current links point to archived paths. Requirements express intent and acceptance criteria, not shipped behavior. | `PRD.md; split supporting contracts later` |
|
||||
| `docs/QUICKSTART.md` | (no title) | `incomplete` | quickstart placeholder | Empty file: 0 bytes and 0 lines. | `USER-GUIDE/getting-started/quickstart.md` |
|
||||
| `docs/README.md` | Mosaic Stack Documentation | `current/verified` | documentation structure contract | Structure, placement, source-of-truth, migration, and link rules were checked in this task; two future blueprint wikilinks are intentionally unresolved. | `README.md` |
|
||||
| `docs/SITEMAP.md` | Documentation Sitemap | `stale/contradicted` | navigation index | 66 current links resolve only against removed pre-archive paths; it must be regenerated after the canonical scaffold and migration map are approved. | `SITEMAP.md` |
|
||||
| `docs/SSO-PROVIDERS.md` | SSO Providers | `partially-verified/contradicted` | SSO operator guide | Required provider environment names and partial-config behavior match `packages/auth`; documented `NEXT_PUBLIC_*_ENABLED` flags are not read by current web code, which discovers providers through `/api/sso/providers`. | `ADMIN-GUIDE/security/sso-providers.md` |
|
||||
| `docs/TASKS-TUI_Improvements.md` | Tasks: TUI Improvements | `stale/historical` | branch-specific TUI task ledger | References an absent worktree and `packages/cli`; Wave 1/2 status and commit claims were not independently reverified against current code. | `tasks/ or archive/` |
|
||||
| `docs/TASKS.md` | Tasks — MVP (Top-Level Rollup) | `active/stale-links` | MVP orchestrator rollup | Active rollup with seven broken workstream links. Status is orchestrator-owned and was not changed by this audit. | `TASKS.md until orchestrator archives it` |
|
||||
| `docs/_old_structure/architecture/ADR-MOS-EGRESS-GATEWAYS.md` | ADR: Optional AI egress gateways for runtime-neutral Mos | `historical/unverified` | archived architecture | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/architecture/channel-protocol.md` | Channel Protocol Architecture | `historical/unverified` | archived architecture | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/architecture/compaction-revocation.md` | Compaction observer revocation and runtime generations | `historical/unverified` | archived architecture | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/architecture/lease-broker-protocol.md` | Authenticated external lease broker protocol | `historical/unverified` | archived architecture | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/architecture/lease-broker-security.md` | WI-1 lease broker security notes | `historical/unverified` | archived architecture | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/architecture/mos-runtime-portability-m1.md` | Mos Runtime Portability M1 — Logical Identity and Fencing | `historical/unverified` | archived architecture | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/architecture/mutator-class-gate.md` | Whole mutator-class lease gate | `historical/unverified` | archived architecture | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/archive/missions/cli-unification-20260404/MISSION-MANIFEST.md` | Mission Manifest — CLI Unification & E2E First-Run | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/cli-unification-20260404/TASKS.md` | Tasks — CLI Unification & E2E First-Run | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/harness-20260321/MISSION-MANIFEST.md` | Mission Manifest — Harness Foundation | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/harness-20260321/PRD.md` | PRD: Harness Foundation — Phase 9 | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/install-ux-hardening-20260405/MISSION-MANIFEST.md` | Mission Manifest — Install UX Hardening | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/install-ux-hardening-20260405/TASKS.md` | Tasks — Install UX Hardening | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/install-ux-v2-20260405/MISSION-MANIFEST.md` | Mission Manifest — Install UX v2 | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/install-ux-v2-20260405/TASKS.md` | Tasks — Install UX v2 | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/install-ux-v2-20260405/iuv-m03-design.md` | IUV-M03 Design: Provider-first intelligent flow + drill-down main menu | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/install-ux-v2-20260405/scratchpad.md` | Install UX v2 — Orchestrator Scratchpad | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/archive/missions/storage-abstraction/TASKS.md` | Tasks — Storage Abstraction Retrofit | `historical/unverified` | archived archive | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/` |
|
||||
| `docs/_old_structure/audits/AUDIT-2026-02-17-framework-consistency.md` | Mosaic Framework Consistency Audit | `historical/unverified` | archived audits | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/documentation/ or reports/security/` |
|
||||
| `docs/_old_structure/briefs/monorepo-consolidation.md` | Brief: Monorepo Consolidation — mosaic/stack → mosaic/mosaic-stack | `historical/unverified` | archived briefs | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or archive/` |
|
||||
| `docs/_old_structure/compaction-refresh/probes/p5_receipt_replay.py` | #!/usr/bin/env python3 | `historical/unverified` | archived compaction-refresh | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/ or reports/qa/` |
|
||||
| `docs/_old_structure/compaction-refresh/probes/p6_constrained_recovery.py` | #!/usr/bin/env python3 | `historical/unverified` | archived compaction-refresh | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/ or reports/qa/` |
|
||||
| `docs/_old_structure/deploy/portainer/README.md` | deploy/portainer/ | `historical/unverified` | archived deploy | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/` |
|
||||
| `docs/_old_structure/deploy/portainer/federated-test.stack.yml` | deploy/portainer/federated-test.stack.yml | `historical/unverified` | archived deploy | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/` |
|
||||
| `docs/_old_structure/design/791-upgrade-config-protection.md` | Design — #791: Framework upgrades must not destroy operator-owned config under `~/.config/mosaic` | `historical/unverified` | archived design | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/decisions/ or plans/` |
|
||||
| `docs/_old_structure/design/framework-constitution/ALPHA-DOD.md` | Constitution Alpha — Definition-of-Done checklist + release notes | `historical/unverified` | archived design | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/decisions/ or plans/` |
|
||||
| `docs/_old_structure/design/prerelease-next-dist-tag-pipeline.md` | npm `@next` prerelease lane | `historical/unverified` | archived design | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/decisions/ or plans/` |
|
||||
| `docs/_old_structure/design/storage-abstraction-middleware.md` | Storage & Queue Abstraction — Middleware Architecture | `historical/unverified` | archived design | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/decisions/ or plans/` |
|
||||
| `docs/_old_structure/federation/ADMIN-CLI.md` | Mosaic Federation — Admin CLI Reference | `historical/unverified` | archived federation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/federation/MILESTONES.md` | Mosaic Stack — Federation Implementation Milestones | `historical/unverified` | archived federation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/federation/MISSION-MANIFEST.md` | Mission Manifest — Federation v1 | `historical/unverified` | archived federation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/federation/PRD.md` | Mosaic Stack — Federation PRD | `historical/unverified` | archived federation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/federation/SETUP.md` | Federated Tier Setup Guide | `historical/unverified` | archived federation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/federation/TASKS.md` | Tasks — Federation v1 | `historical/unverified` | archived federation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/deployment/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/FLEET-CONFIG-DOCS-IA-CHECKLIST.md` | Fleet Configuration Management — Documentation IA Acceptance Checklist | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/FLEET-LAUNCH.md` | Fleet Launch Runbook | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/LEGACY-EXAMPLE-PROFILE-DISPOSITION-INVENTORY.md` | Fleet Configuration Management — Legacy Example, Profile, and Service Disposition Inventory | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/NORTH_STAR.md` | Mosaic Fleet — NORTH STAR | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/NORTH_STAR.yaml` | Mosaic Fleet — NORTH_STAR (machine-readable source of truth) | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/PRD-fleet-suite.md` | PRD — Mosaic Fleet Suite (init, configure, operate) | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/PRD.md` | PRD — Fleet Phase 2: Operator Observability | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/README.md` | Fleet Configuration Management | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/TASKS.md` | Tasks — W-FLEET (Fleet) Phase 2: Observability | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/backlog-conventions.md` | Fleet Backlog Conventions | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/concepts/desired-vs-observed-state.md` | Desired, Derived, and Observed Fleet State | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/concepts/generated-env-launch-chain.md` | Generated Environment Launch Chain | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/concepts/identity-class-runtime.md` | Fleet Identity, Class, and Runtime | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/concepts/role-authority-and-leases.md` | Fleet Role Authority and Leases | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/examples/roster-v2.yaml` | (no title) | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/f4-matrix-connector.md` | F4 — Orchestrator chat connector + Matrix (local homeserver) | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/how-to/configure-tess-interaction.md` | Configure an Interaction Instance | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/how-to/configure-ultron-validator.md` | Configure a Validator Instance | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/how-to/create-update-delete-agent.md` | Create, Inspect, Update, and Delete a Local Fleet Agent | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/how-to/customize-roles.md` | Customize Fleet Roles | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/how-to/start-stop-restart.md` | Safely Reconcile and Control a Local Fleet Agent | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/migration/example-profile-disposition.md` | Executable Fleet Example, Profile, and Service-Preset Dispositions | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/migration/legacy-class-aliases.md` | Legacy Fleet Class Aliases | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/migration/v1-to-v2.md` | Previewing a Fleet Roster v1-to-v2 Migration | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/north-star.md` | Mosaic Fleet — North Star | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/operations/backup-restore.md` | Fleet Configuration Backup and Restore Boundary | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/operations/env-quarantine.md` | Environment Quarantine Operations | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/operations/reconcile-and-recover.md` | Reconcile and Recover a Local Fleet | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/operations/systemd-tmux-troubleshooting.md` | Systemd and tmux Troubleshooting | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/operations/upgrade-assets.md` | Upgrade and Installed-Asset Drift | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/agent-mutations.md` | Local Fleet Agent Mutations | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/cli.md` | Fleet Control-Plane CLI | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/generated-env-boundary.md` | Fleet Generated Environment Boundary | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/lifecycle-transitions.md` | Local Fleet Lifecycle Transitions | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/role-classes.md` | Fleet Role Classes and Authority | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/roster-v2-fields.md` | Fleet Roster v2 Structural Contract | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/roster-v2.schema.json` | (no title) | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/fleet/reference/status-and-drift.md` | Local Fleet Status and Drift | `historical/unverified` | archived fleet | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `ADMIN-GUIDE/operations/ and DEVELOPER-GUIDE/architecture/` |
|
||||
| `docs/_old_structure/guides/admin-guide.md` | Mosaic Stack — Admin Guide | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/deployment.md` | Deployment Guide | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/dev-guide.md` | Mosaic Stack — Developer Guide | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/fleet-local-canary.md` | Local Fleet Canary | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/lease-broker-operations.md` | Lease broker operations | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/migrate-tier.md` | Migrating to the Federated Tier | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/mos-connector-lease-operations.md` | Mos Connector Lease Operations — M1 | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/upgrade-safety-and-recovery.md` | Upgrade Safety & Recovery | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/guides/user-guide.md` | Mosaic Stack — User Guide | `historical/unverified` | archived guides | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, or DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/mission-control/BOARD.md` | Mission Control Plane — Feature Board | `historical/unverified` | archived mission-control | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/ or archive/` |
|
||||
| `docs/_old_structure/mission-control/MISSION-MANIFEST.md` | Mission Manifest — Mosaic Mission Control Plane | `historical/unverified` | archived mission-control | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/ or archive/` |
|
||||
| `docs/_old_structure/mission-control/PRD.md` | PRD: Mosaic Mission Control Plane | `historical/unverified` | archived mission-control | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/ or archive/` |
|
||||
| `docs/_old_structure/mission-control/TASKS.md` | Tasks — Mosaic Mission Control Plane | `historical/unverified` | archived mission-control | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/ or archive/` |
|
||||
| `docs/_old_structure/native-kanban-sot/DOCUMENTATION-CHECKLIST.md` | Documentation Completion Checklist — Native Kanban/SOT Canon | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/INDEX.md` | Native Kanban/SOT Canon | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/KBN-010-THREAT-AUTH-CONSTRAINT-GATE.md` | KBN-010 — Threat, Authorization, and Constraint-Impact Gate | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md` | KBN-101 — Database Runtime/Migration Role Split | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/KBN-101-ENVELOPE-A.md` | KBN-101 — B1/B2 Envelope A (v6, FINAL) — Declarative Sink-RBAC + Per-Role Credential/Connection-Selection + RLS Write-Source (INSERT tenant-bound, single-compound-or-RESTRICTIVE composition) + Sink-Resident User-Override + Read/USING Enforcement | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/MISSION-MANIFEST.md` | Mission Manifest — Mosaic Native Kanban and Canonical Task SOT P0–P3 | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/SHARED-CONTRACT.md` | Native Kanban/SOT — Remediated Shared Contract v1 | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/TASKS.md` | Native Kanban/SOT P0–P3 — Dependency-Ordered Build Slices | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/contracts/health-state.v1.ts` | (no title) | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/contracts/kanban-schema.v1.ts` | (no title) | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/contracts/mechanical-coordinator.v1.ts` | (no title) | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/contracts/recovery-posture.v1.ts` | (no title) | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/native-kanban-sot/tsconfig.json` | (no title) | `historical/unverified` | archived native-kanban-sot | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/, tasks/, and reports/` |
|
||||
| `docs/_old_structure/plans/2026-03-13-gateway-security-hardening.md` | Gateway Security Hardening Implementation Plan | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/2026-03-15-agent-platform-architecture.md` | Agent Platform Architecture — Slash Commands, Workspaces, Task Orchestration & Agent Isolation | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/2026-03-15-wave2-tui-layout-navigation.md` | Wave 2 — TUI Layout & Navigation Implementation Plan | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/2026-05-06-hermes-mosaic-alignment.md` | Hermes-Mosaic Alignment Plan | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/2026-05-07-coordination-resilience.md` | Mosaic Stack ↔ Hermes Coordination Resilience | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/2026-08-09-webui-fleet-claude-bridge.md` | WebUI Fleet Claude Bridge Implementation Plan | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/agent-reflection-loop-PRD.md` | PRD — Agent Reflection Loop (durable kernel) | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/authentik-sso-setup.md` | Authentik SSO Setup | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/chroot-sandboxing.md` | Chroot Agent Sandboxing — Process Isolation for Agent Tool Execution | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/gatekeeper-service.md` | Gatekeeper Service — PR Review, Quality Gates & Merge Authority | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/gateway-token-recovery.md` | Gateway Admin Token Recovery — Implementation Plan | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/plans/task-queue-unification.md` | Task Queue Unification — @mosaicstack/queue as Unified Orchestration Layer | `historical/unverified` | archived plans | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `plans/ or DEVELOPER-GUIDE/architecture/decisions/` |
|
||||
| `docs/_old_structure/remediation/BOARD-LEDGER.md` | ### **D-1 / P-ACTIVATION + hygiene — committed `.npmrc` hard-pins `store-dir=/root/.local/share/pnpm/store`.** | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/remediation/BOARD.md` | mos-remediation — LIVE BOARD (keep < 8 KB) | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/remediation/DECOMP-OPUS.md` | DECOMP-OPUS — Adversarial Task Decomposition (ROBUSTNESS SIDE) | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/remediation/DECOMP-SOL.md` | Adversarial Decomposition — Pragmatic / Shortest-Path Side | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/remediation/KICKSTART.md` | mos-remediation — Orchestrator Kickstart / Compaction-Survival Resume | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/remediation/MACP-WIRING-SCOUT.md` | MACP wiring investigation | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/remediation/MISSION.md` | Mosaic Stack Remediation — Mission Charter | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/remediation/TASKS.md` | Remediation Backlog — Reconciled Execution Plan | `historical/unverified` | archived remediation | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/deferred/ or tasks/` |
|
||||
| `docs/_old_structure/reports/code-review/756-code-review.md` | Independent Code Review — #756 Official Discord Channel Plugin | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/code-review/gateway-security-20260313.md` | Code Review Report — Gateway Security Hardening | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/compaction-refresh/830-documentation-checklist.md` | #830 Documentation Completion Checklist | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/deferred/758-fleet-config-deferrals.md` | FCM-M5-001 Fleet Documentation Deferrals and Holds | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/documentation/756-discord-plugin-checklist.md` | Documentation Completion Checklist — #756 Official Discord plugin | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/documentation/758-fleet-config-ia-closure.md` | FCM-M5-001 Fleet Documentation IA Closure Evidence | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/native-kanban-sot/canon-final-rereview-go.md` | Native Kanban/SOT canon independent re-review 2 | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/native-kanban-sot/canon-initial-review-no-go.md` | Independent Review — Native Kanban/SOT Canon | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/native-kanban-sot/kbn-101-contract-security-review-82ce325.md` | KBN-101 contract independent security/architecture review | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/native-kanban-sot/ultron-final-go.md` | #751 Native Kanban/SOT canonical publication — Ultron final gate | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/qa/gateway-security-20260313.md` | QA Report — Gateway Security Hardening | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/reports/security/756-security-review.md` | Security Review — Issue #756 | `historical/unverified` | archived reports | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/<category>/` |
|
||||
| `docs/_old_structure/requirements/native-kanban-sot.md` | Native Kanban and Canonical Task SOT — Canonical Requirements | `historical/unverified` | archived requirements | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `PRD.md or DEVELOPER-GUIDE/architecture/requirements/` |
|
||||
| `docs/_old_structure/reviews/consolidation-board-memo.md` | Board of Directors — Monorepo Consolidation Brief | `historical/unverified` | archived reviews | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `reports/code-review/` |
|
||||
| `docs/_old_structure/rfcs/RFC-001-MACP-MATRIX-NATIVE.md` | RFC-001 — MACP: A Mosaic-Native, Matrix-Native Comms Layer | `historical/unverified` | archived rfcs | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/rfcs/` |
|
||||
| `docs/_old_structure/rfcs/RFC-002-INSTALL-CONFIG-TOPOLOGY.md` | RFC-002 — Install, Configuration & Topology for the Mosaic Matrix/MACP Comms System | `historical/unverified` | archived rfcs | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `DEVELOPER-GUIDE/architecture/rfcs/` |
|
||||
| `docs/_old_structure/scratchpads/1000-rm-61-ci-contract-exemption.md` | RM-61 — CI contract exemption for #1000 teardown artifact | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/2026-06-20-fleet-cli-local-canary.md` | Fleet CLI Local Canary Dogfood — 2026-06-20 | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/2026-06-20-fleet-release-hardening.md` | Fleet release hardening | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/387-updater-wrapper-gitea-20260404.md` | Scratchpad — issue #387 updater simplification + Gitea wrapper repo context | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/41-plugin-host.md` | Scratchpad — P5-001 Plugin Host | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/462-fed-m3-04-scope-service.md` | Scratchpad — FED-M3-04 Scope Service | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/462-fed-m3-06-get-verb.md` | Scratchpad — FED-M3-06 get verb | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/536-wrapper-login-pin.md` | Issue 536 Wrapper Login Pin Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/544-agent-reflection-loop.md` | Scratchpad — #544 Agent Reflection Loop (durable kernel) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/559-560-wrapper-eval-login-20260620.md` | Wrapper hardening fold-in: #559 (eval removal) + #560 (host-derived login) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/561-python-is-python3.md` | Issue #561 — Bare python on agent hosts | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/631-reseed-preserves-fleet.md` | #631 — re-seed must preserve user fleet data (CRITICAL data-loss) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/633-comms-block-runbook.md` | #633 — comms-block emitter + FLEET-LAUNCH runbook | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/672-fleet-personas-timeout.md` | Scratchpad — fleet-personas spec timeout | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/703-wrapper-interactive-auth.md` | #703 Git Wrapper Interactive and Auth Resilience | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/747-wsa-dehardcode.md` | #747 — De-hardcode orchestrator and interaction agent names | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/751-native-kanban-canon.md` | Issue #751 — Native Kanban/SOT canonical publication | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/753-kbn010-threat-gate.md` | Issue #753 — KBN-010 threat, authorization, and constraint-impact gate | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/755-mos-logical-identity-fencing.md` | Issue #755 — Logical Mos identity and connector lease fencing | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/756-official-discord-plugin.md` | Scratchpad — #756 Official Discord channel plugin | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/758-fcm-m1-002-shared-role-resolution.md` | FCM-M1-002 — Shared role resolution | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/758-fcm-m1-003-example-profile-dispositions.md` | FCM-M1-003 — Executable example/profile/service-preset dispositions | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/758-fcm-m2-002-fleet-agent-crud.md` | FCM-M2-002 — Generation-Guarded Fleet Agent CRUD | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/758-fcm-m3-001-local-reconciler.md` | FCM-M3-001 — Local roster-owned reconciliation and lifecycle | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/758-fcm-m3-002-reconciler-lifecycle-gates.md` | FCM-M3-002 — Reconciler lifecycle acceptance gates | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/758-fcm-m4-001-v1-v2-migrator.md` | FCM-M4-001 — v1-to-v2 inventory, preview, and migrator | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/771-kbn101-db-role-split.md` | Scratchpad — KBN-101 DB runtime/migration role split (#771) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/791-upgrade-config-protection.md` | Scratchpad — #791 Upgrade config protection (ms-791 worker lane) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/804-install-unknown-flags.md` | Issue #804 — fail closed on unknown installer arguments | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/807-glpi-partial-content.md` | Issue #807 — GLPI list wrappers accept HTTP 206 | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/808-agent-send-sender-identity.md` | Issue #808 — agent-send sender identity | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/812-pr-review-comment.md` | Issue #812 — durable Gitea PR review comments | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/824-mosaic-skill-cli.md` | Issue #824 — Mosaic skill CLI and Claude bridge auto-sync | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/828-lease-broker.md` | WI-1 Scratchpad — Authenticated external lease broker | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/829-mutator-gate.md` | WI-2 Scratchpad — Whole mutator-class gate | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/830-compaction-revoke.md` | WI-3 Scratchpad — Compaction revocation and runtime-generation rollover | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/832-receipt-challenge-protocol.md` | #832 Receipt-challenge protocol — build scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/833-constrained-recovery-command.md` | #833 constrained recovery command — build scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/838-broker-acceptance-flake.md` | Issue #838 — Broker acceptance socket flake | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/B1-next-durable-publish-design.md` | B1 / @next Durable Publish Pipeline — Design | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/B2-skills-sync-path.md` | B2 — Fresh-install skills sync path | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/B3-wizard-gateway-health-order.md` | B3 — Wizard completion ordering | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/B4-wizard-step-dedup.md` | B4 — Wizard step deduplication | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/BUG-CLI-scratchpad.md` | BUG-CLI Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/FED-M3-05-list-verb.md` | FED-M3-05 — Federation List Verb Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/FED-M3-07-capabilities.md` | FED-M3-07 — Capabilities Verb Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/FED-M3-09-query-source.md` | FED-M3-09 — Query Source Service Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/FED-M3-10-integration-tests.md` | FED-M3-10 — Federation M3 Integration Tests | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/bug-196-admin-redirect.md` | BUG-196: Admin Page Redirect Issue | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/ci-docker-publish-20260330.md` | Scratchpad: CI Docker Publish (2026-03-30) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/cli-unification-20260404.md` | Mission Scratchpad — CLI Unification & E2E First-Run | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/f3-m3-update-reseed.md` | F3-m3 — `mosaic update` re-seeds framework + relaunches agents (R13) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/f4-matrix-connector.md` | F4 — Orchestrator chat connector + Matrix (#616) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fcm-m2-001-generated-env-boundary.md` | FCM-M2-001 — Generated Environment Boundary | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fcm-m5-001-fleet-config-operator-docs.md` | FCM-M5-001 — Fleet configuration operator documentation | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fix-ci-migrations-20260330.md` | Scratchpad — fix-ci-migrations-20260330 | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fix-turbo-env-passthrough.md` | Task Scratchpad — Turbo DATABASE_URL passthrough | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fleet-cli-local-canary-review-fixes.md` | Fleet CLI Local Canary Review Fixes | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fleet-comms-onboarding.md` | Fleet onboarding-injection — comms cheat-sheet + peer roster (#620) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fleet-enhancer-floor.md` | Fleet enhancer role + two-agent floor (#614) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fleet-observability-phase2.md` | Scratchpad — Fleet Phase 2: Observability (W-FLEET) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fleet-polish-bundle.md` | Fleet-polish bundle — boot-survival symmetry (#611) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/fleet-standup-fixes.md` | Fleet stand-up fixes — model_hint→--model + socket-default trap (#626) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/gateway-install-ux-20260404.md` | Gateway Install UX Fixes — 2026-04-04 | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/gateway-security-20260313.md` | Gateway Security Hardening Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/git-wrapper-rollup-20260526.md` | Git Wrapper Rollup — 2026-05-26 | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/h1-heartbeat-readiness.md` | H1 — heartbeat readiness detection | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/h1b-pane-idle-signal.md` | H1b — tmux pane idle signal wiring | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/h2-readiness-available.md` | H2 — readiness semantics: available, not stuck | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/harness-20260321.md` | Mission Scratchpad — Harness Foundation | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/install-ux-hardening-20260405.md` | Install UX Hardening — IUH-M01 Session Notes | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/installer-next-fast-npm-20260625.md` | Installer `--next` fast npm lane — 2026-06-25 | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/installer-next-lane-20260624.md` | Scratchpad — installer `--next` lane | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/issue-766-exact-fleet-comms.md` | Issue 766 — exact cross-harness fleet comms targeting | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/m3-001-provider-adapter.md` | M3-001 Provider Adapter Pattern — Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/macp-oc-bridge-20260330.md` | Scratchpad: MACP OC Bridge (2026-03-30) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/ms-792-fleet-enoent-installer.md` | ms-792 — Fleet roster error handling and installer heading | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/mvp-20260312.md` | Mission Scratchpad — MVP | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/north-star-doctrine.md` | north-star doctrine consolidation (#620-adjacent doc PR) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p5-003-telegram-plugin.md` | Scratchpad — P5-003 Telegram Plugin | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p5-004-authentik-sso.md` | P5-004 Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p5-overlay-composer.md` | P5 — Overlay composer + cross-harness (compose-contract) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p6-docs-compliance-alpha.md` | P6 — Docs, compliance matrix, alpha tag (constitution capstone) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p8-001-sso-providers.md` | P8-001 — WorkOS + Keycloak SSO Providers | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p8-009-tui-slash-commands.md` | P8-009: TUI Phase 1 — Slash Command Parsing | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p8-010-command-registry.md` | P8-010 Scratchpad — Gateway Phase 2: CommandRegistryService + CommandExecutorService | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p8-012-agent-provider-commands.md` | P8-012 Scratchpad — Gateway /agent, /provider, /mission, /prdy, /tools Commands | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p8-016-tool-hardening.md` | P8-016: Security — Tool Path Hardening + Sandbox Escape Prevention | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/p8-019-verify.md` | P8-019 Verification — Phase 8 Platform Architecture | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/rm-01-reproducible-checkout.md` | RM-01 — Reproducible checkout | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/rm-03-queue-guard.md` | RM-03 — CI Queue Guard Repair | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/t-a292e96f-gitea-pr-metadata.md` | t_a292e96f — Gitea PR metadata wrapper fix | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/t_301e4e3b-pr-merge-gitea-empty-uid.md` | Scratchpad: t_301e4e3b pr-merge.sh Gitea empty-uid fallback | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/t_5aab9cc8-pr-merge-eval-injection.md` | t_5aab9cc8 — pr-merge.sh eval injection remediation | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/task-mission-ownership-20260313.md` | Task Ownership Gap Fix Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-20260712.md` | Scratchpad — Tess Interaction Agent | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m1-002-provider-registry.md` | TESS-M1-002 — Provider Registry | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m1-003-fleet-provider.md` | TESS-M1-003 — Fleet/tmux Runtime Provider | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m1-obs-001.md` | TESS-M1-OBS-001 Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m1-sec-001.md` | TESS-M1-SEC-001 — Command authorization and exact-action approval | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m1-sec-004-discord-ingress.md` | Scratchpad — TESS-M1-SEC-004 Discord ingress | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m1-sec-006-session-gc-scope.md` | Scratchpad — TESS-M1-SEC-006 Session GC scope | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m2-001-pi-service.md` | TESS-M2-001 — Pi Interaction Service | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m2-002-durable-state.md` | TESS-M2-002 — Durable Tess State | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m4-001-mos-coordination.md` | TESS-M4-001 — Mos Coordination | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tess-m4-003-operator-plugins.md` | TESS-M4-003 — Operator Plugin Foundations | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/tools-md-seeding-20260411.md` | Hotfix Scratchpad — `install.sh` does not seed `TOOLS.md` | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/update-checker-package-20260404.md` | Scratchpad — updater package target fix (#382) | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/webui-fleet-bridge-plan.md` | WebUI Fleet Bridge Planning Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/webui-p2-data-auth.md` | WebUI Phase P — P2 Data + Auth Scratchpad | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/scratchpads/yolo-runtime-initial-arg-20260411.md` | Hotfix Scratchpad — `mosaic yolo <runtime>` passes runtime name as initial user message | `historical/unverified` | archived scratchpads | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `archive/ or tasks/ after retention review` |
|
||||
| `docs/_old_structure/tasks/544-agent-reflection-loop.md` | 544: Agent Reflection Loop — durable kernel | `historical/unverified` | archived tasks | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/` |
|
||||
| `docs/_old_structure/tasks/WP1-forge-package.md` | WP1: packages/forge — Forge Pipeline Package | `historical/unverified` | archived tasks | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/` |
|
||||
| `docs/_old_structure/tasks/WP2-macp-package.md` | WP2: packages/macp — MACP Protocol Package | `historical/unverified` | archived tasks | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/` |
|
||||
| `docs/_old_structure/tasks/WP3-mosaic-framework-plugin.md` | WP3: plugins/mosaic-framework — OC Rails Injection Plugin | `historical/unverified` | archived tasks | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `tasks/` |
|
||||
| `docs/_old_structure/tess/ADMIN-GUIDE.md` | Tess Administration | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/ARCHITECTURE.md` | Tess Architecture | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/DEVELOPER-GUIDE.md` | Tess Developer Guide | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/M4-003-OPERATOR-PLUGIN-SKETCH.md` | TESS-M4-003 Operator Plugin Sketch | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/M5-003-DOCUMENTATION-CHECKLIST.md` | TESS-M5-003 Documentation Checklist | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/M5-MIGRATION-CUTOVER.md` | TESS-MIG-001 — Cutover Procedure | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/M5-MIGRATION-INVENTORY.md` | TESS-MIG-001 — Hermes → Mosaic Evidence Inventory | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/M5-MIGRATION-RETENTION-DEPRECATION.md` | TESS-MIG-001 — Retention and Legacy Deprecation Policy | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/M5-MIGRATION-ROLLBACK.md` | TESS-MIG-001 — Rollback Procedure | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/MIGRATION-INVENTORY.md` | Tess Capability Migration Inventory | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/MISSION-MANIFEST.md` | Mission Manifest — Tess Interaction Agent | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/MOS-COORDINATION.md` | Tess–Mos Coordination Contract Sketch | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/OPERATIONS-GUIDE.md` | Tess Operations and Recovery | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/PLUGIN-GUIDE.md` | Tess Plugin Authoring | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/TASKS.md` | Tasks — Tess Interaction Agent | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/THREAT-MODEL.md` | Tess Threat Model | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/USER-GUIDE.md` | Tess User Guide | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/VERIFICATION-MATRIX.md` | Tess Verification Matrix | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/hermes-runtime-adapter-design.md` | TESS-HRM-001 — Hermes runtime adapter boundary | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/_old_structure/tess/qualification/2026-07-14-option2-runtime-portability.md` | Tess / Option 2 runtime-portability qualification — 2026-07-14 | `historical/unverified` | archived tess | Moved unchanged during the 2026-08-10 archive operation; claims require evidence review before resurfacing. | `USER-GUIDE/, ADMIN-GUIDE/, and DEVELOPER-GUIDE/ by page purpose` |
|
||||
| `docs/openapi-tess.yaml` | (no title) | `partially-verified/legacy-location` | Tess-scoped OpenAPI contract | PyYAML parses OpenAPI 3.1.0 with 17 paths. It covers Tess interaction, Mos coordination, and memory routes, but is not at `docs/API/` and is not a complete gateway contract. | `API/ (scoped Tess contract or consolidated OPENAPI.yaml)` |
|
||||
| `docs/plans/2026-08-10-docs-information-architecture-design.md` | Documentation Information Architecture Design | `current/working` | approved plan | Task-local planning artifact; not a statement of shipped behavior. | `plans/` |
|
||||
| `docs/plans/2026-08-10-docs-structure-readme.md` | Documentation Structure README Implementation Plan | `current/working` | approved plan | Task-local planning artifact; not a statement of shipped behavior. | `plans/` |
|
||||
| `docs/scratchpads/DOCS-IA-001.md` | DOCS-IA-001 — Documentation Information Architecture | `current/working` | task scratchpad | Task-local working notes; not a canonical product source. | `scratchpads/` |
|
||||
|
||||
## Navigation and link audit
|
||||
|
||||
- Total scanned links: **219**.
|
||||
- Current/workflow links: **97**; unresolved current links excluding the two intentional README blueprint links: **83**.
|
||||
- Archive links: **122**; unresolved archive links: **12**.
|
||||
|
||||
### Broken-link clusters
|
||||
|
||||
| Target | Occurrences | Current sources |
|
||||
| --------------------------------------------------------- | ----------: | ------------------------------------------- |
|
||||
| `./scratchpads/mvp-20260312.md` | 3 | `docs/MISSION-MANIFEST.md` |
|
||||
| `./federation/TASKS.md` | 3 | `docs/MISSION-MANIFEST.md`, `docs/TASKS.md` |
|
||||
| `./federation/MISSION-MANIFEST.md` | 2 | `docs/MISSION-MANIFEST.md`, `docs/TASKS.md` |
|
||||
| `./fleet/FLEET-CONFIG-DOCS-IA-CHECKLIST.md` | 2 | `docs/PRD.md`, `docs/TASKS.md` |
|
||||
| `./fleet/LEGACY-EXAMPLE-PROFILE-DISPOSITION-INVENTORY.md` | 2 | `docs/PRD.md`, `docs/TASKS.md` |
|
||||
| `tess/USER-GUIDE.md` | 2 | `docs/SITEMAP.md` |
|
||||
| `tess/PLUGIN-GUIDE.md` | 2 | `docs/SITEMAP.md` |
|
||||
| `./tess/MISSION-MANIFEST.md` | 1 | `docs/MISSION-MANIFEST.md` |
|
||||
| `./native-kanban-sot/MISSION-MANIFEST.md` | 1 | `docs/MISSION-MANIFEST.md` |
|
||||
| `./native-kanban-sot/KBN-101-DB-ROLE-SPLIT.md` | 1 | `docs/PRD.md` |
|
||||
| `architecture/lease-broker-protocol.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `guides/lease-broker-operations.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `architecture/lease-broker-security.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `architecture/mutator-class-gate.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `architecture/compaction-revocation.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `guides/user-guide.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `guides/dev-guide.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/README.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/concepts/desired-vs-observed-state.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/concepts/identity-class-runtime.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/concepts/role-authority-and-leases.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/concepts/generated-env-launch-chain.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/reference/roster-v2-fields.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/reference/cli.md` | 1 | `docs/SITEMAP.md` |
|
||||
| `fleet/reference/lifecycle-transitions.md` | 1 | `docs/SITEMAP.md` |
|
||||
|
||||
### Link-audit interpretation
|
||||
|
||||
- The 66 `SITEMAP.md` failures are a navigation migration blocker, not evidence that every archived page is false.
|
||||
- The `PRD.md`, `TASKS.md`, and `MISSION-MANIFEST.md` failures show that current control documents still point at the pre-archive layout.
|
||||
- The two unresolved wikilinks in `docs/README.md` are intentional target-tree blueprint links and should resolve when the architecture scaffold is created.
|
||||
- Link repair must occur with page classification; blindly changing paths can turn a historical or draft page into an accidental current instruction.
|
||||
|
||||
## Repository truth dependencies
|
||||
|
||||
The following tracked files currently depend on documentation paths that are absent from the working tree:
|
||||
|
||||
| Source file | Dependency | Risk |
|
||||
| -------------------------------------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------- |
|
||||
| `README.md` | legacy docs path | Installed framework guidance may retain stale links. |
|
||||
| `apps/gateway/src/federation/ca.service.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `apps/gateway/src/federation/oid.util.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `apps/gateway/src/federation/scope-schema.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/mosaic/framework/fleet/README.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/board.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/code.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/decomposition.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/documentation.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/enhancer.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/merge-gate.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/operator.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/orchestrator.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/planner.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/rebase.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/review.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/security-review.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/session-review.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/fleet/roles/site-tester.md` | `docs/fleet/` | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/framework/systemd/user/README.md` | legacy docs path | Installed framework guidance may retain stale links. |
|
||||
| `packages/mosaic/src/commands/fleet-north-star.spec.ts` | `docs/fleet/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/mosaic/src/commands/fleet.ts` | `docs/fleet/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/mosaic/src/fleet/fleet-documentation.spec.ts` | `docs/fleet/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/mosaic/src/fleet/roster-v2.spec.ts` | `docs/fleet/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/mosaic/src/lease-broker/framework_skill_portability_unittest.py` | legacy docs path | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/mosaic/src/mutator-gate/mutator-gate.acceptance.spec.ts` | legacy docs path | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/types/src/federation/error.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/types/src/federation/request.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/types/src/federation/response.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/types/src/federation/source-tag.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
| `packages/types/src/federation/verbs.ts` | `docs/federation/` | Tests or runtime path resolution may fail if the source is not updated with the document move. |
|
||||
|
||||
High-risk consumers include `packages/mosaic/src/commands/fleet.ts`, fleet path-resolution tests, lease-broker portability tests, federation source comments, and root `README.md` operator links. These must be handled before deleting the archived source pages.
|
||||
|
||||
## Truth-audit evidence collected
|
||||
|
||||
| Surface | Evidence | Result |
|
||||
| --------------------------------- | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| SSO provider environment contract | `packages/auth/src/sso.ts`, auth tests, `.env.example` | Provider core names and partial-config behavior align; web feature-flag claim does not. |
|
||||
| SSO web flow | `apps/web` login/provider pages and `/api/sso/providers` calls | Dynamic provider discovery is current; `NEXT_PUBLIC_*_ENABLED` documentation is stale. |
|
||||
| Performance report | Seven named implementation files exist; DB pool, upsert, indexes, GC, and Next config markers found | Static implementation alignment is partial; performance metrics and production traffic are unverified. |
|
||||
| Tess OpenAPI | PyYAML parse of `docs/openapi-tess.yaml` | Valid OpenAPI 3.1 syntax with 17 paths; legacy location and incomplete full-gateway coverage remain. |
|
||||
| TUI documents | `packages/cli` and old worktree absent; `packages/mosaic/src/tui` exists | TUI document paths are contradicted/stale. |
|
||||
| Root navigation | Relative link resolver and repository reference scan | Current docs and code still depend on pre-archive paths. |
|
||||
| Documentation root hygiene | Baseline `.gitignore` and `guides/DOCUMENTATION.md` | `docs/reports/` is required for evidence; the conflicting blanket ignore rule was identified and subsequently removed. |
|
||||
|
||||
## Recommended migration order
|
||||
|
||||
1. **Scaffold indexes without moving content:** create the required book/API `README.md` files and architecture index pages. Keep them explicit about what is not migrated yet.
|
||||
2. **Repair current control-plane navigation:** classify the workstream manifests, then update `SITEMAP.md`, `MISSION-MANIFEST.md`, and `TASKS.md` through the orchestrator-owned process. Do not silently change task status.
|
||||
3. **Migrate high-value operator/user material:** extract `QUICKSTART`, SSO, deployment, recovery, and user workflow pages into the appropriate books. Re-verify every command and environment variable during migration.
|
||||
4. **Migrate developer architecture and API contracts:** split mixed `fleet`, `federation`, `tess`, architecture, RFC, and requirements material. Move the Tess contract into `API/` and decide whether it remains scoped or becomes part of a consolidated gateway OpenAPI contract.
|
||||
5. **Resolve source/test dependencies:** update code comments, fixture paths, tests, and framework templates only alongside the corresponding documentation move. Run the relevant package tests after each dependency group.
|
||||
6. **Retain evidence deliberately:** place historical reports, plans, scratchpads, task snapshots, and reviews in their artifact directories. Promote only claims with current evidence.
|
||||
7. **Quarantine cleanup:** remove `_old_structure/` only after link, source-reference, and historical-retention checks pass.
|
||||
|
||||
## Human validation queue
|
||||
|
||||
The following decisions require product-owner or maintainer confirmation rather than static inference:
|
||||
|
||||
- Which requirements in the draft PRD remain active for the current release, versus historical or superseded workstreams.
|
||||
- Whether the MVP/federation/Tess/Kanban manifests are still active control documents or should be archived.
|
||||
- Which TUI work was actually merged and where its current source of truth lives.
|
||||
- Whether the Tess OpenAPI document is intended to be a scoped contract or the first portion of the complete gateway contract.
|
||||
- Whether `NEXT_PUBLIC_WORKOS_ENABLED` and `NEXT_PUBLIC_KEYCLOAK_ENABLED` are obsolete configuration variables or still supported by a deployment surface not present in this checkout.
|
||||
- Which historical security, migration, and deployment procedures are safe to preserve as reference and which must be marked explicitly non-operative.
|
||||
|
||||
## Audit limitations
|
||||
|
||||
- This is a static repository audit. It did not start Gateway/Web, PostgreSQL, Valkey, Compose, or external identity providers.
|
||||
- No external agent session was used because the existing fleet sessions were explicitly standing down; parallel discovery was performed with isolated read-only scans in this coordinating session.
|
||||
- At the audit baseline, `docs/reports/` was ignored by `.gitignore` and this report required force-add. The migration subsequently removed the blanket ignore rule.
|
||||
- “Historical/unverified” does not mean the original author was wrong; it means the page is not safe to treat as current without evidence.
|
||||
- Claims involving production topology, external services, latency, security certification, or merged PR state need independent evidence beyond file presence.
|
||||
|
||||
## Reproduction commands
|
||||
|
||||
```bash
|
||||
find docs -type f -not -path 'docs/.obsidian/*' -print | sort
|
||||
rg -n --hidden --glob '!node_modules/**' --glob '!.git/**' 'docs/(fleet|federation|architecture|tess|native-kanban-sot)' apps packages plugins scripts tools README.md
|
||||
pnpm exec prettier --check docs/README.md
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [[README|Documentation structure contract]]
|
||||
- [[plans/2026-08-10-docs-information-architecture-design|Approved information architecture design]]
|
||||
- [[plans/2026-08-10-docs-catalog-audit|Catalog and truth-audit plan]]
|
||||
- [[scratchpads/DOCS-IA-002-catalog-audit|Catalog audit scratchpad]]
|
||||
@@ -14,18 +14,18 @@
|
||||
|
||||
## Acceptance mapping
|
||||
|
||||
| Checklist area | Evidence |
|
||||
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Roster authority and fail-closed legacy handling | Root PRD FCM-REQ-01/05/08; desired/observed and quarantine pages. |
|
||||
| Classes and authority | Root PRD FCM-REQ-07; role authority concept/reference; configurable interaction/validator how-tos. |
|
||||
| Lifecycle | Root PRD FCM-REQ-04; lifecycle transition table and operator lifecycle how-to. |
|
||||
| Local-only generated launch boundary | Root PRD FCM-REQ-05/09; generated launch concept/reference. |
|
||||
| Complete DAG and artifact inventory | `docs/TASKS.md`; M0 inventory; executable disposition tests. |
|
||||
| IA pages | Every path named by the M0 checklist exists and is linked from `docs/fleet/README.md`. |
|
||||
| Examples | `docs/fleet/examples/roster-v2.yaml` validates through production v2 compiler/shared resolver; shipped artifact dispositions validate through declared production readers. |
|
||||
| Links | Deterministic local Markdown link test covers the entire fleet book and sitemap, including local heading-fragment resolution. |
|
||||
| Checklist area | Evidence |
|
||||
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Roster authority and fail-closed legacy handling | Root PRD FCM-REQ-01/05/08; desired/observed and quarantine pages. |
|
||||
| Classes and authority | Root PRD FCM-REQ-07; role authority concept/reference; configurable interaction/validator how-tos. |
|
||||
| Lifecycle | Root PRD FCM-REQ-04; lifecycle transition table and operator lifecycle how-to. |
|
||||
| Local-only generated launch boundary | Root PRD FCM-REQ-05/09; generated launch concept/reference. |
|
||||
| Complete DAG and artifact inventory | `docs/TASKS.md`; M0 inventory; executable disposition tests. |
|
||||
| IA pages | Every path named by the M0 checklist exists and is linked from `docs/fleet/README.md`. |
|
||||
| Examples | `docs/fleet/examples/roster-v2.yaml` validates through production v2 compiler/shared resolver; shipped artifact dispositions validate through declared production readers. |
|
||||
| Links | Deterministic local Markdown link test covers the entire fleet book and sitemap, including local heading-fragment resolution. |
|
||||
| Sensitive/example safety | Validator scans backtick- and tilde-fenced fleet-book examples plus the canonical roster for sensitive-looking keys, common credential formats (including Anthropic, OpenAI project, and Stripe restricted keys), path-qualified privileged commands, package-manager/root commands, arbitrary command override, and hardcoded Tess/Ultron identities; findings report only file/block and violation kind, never matched values. |
|
||||
| Holds | `docs/reports/deferred/758-fleet-config-deferrals.md` records M3-002, M4-002, M5-002, compatibility, and repository-structure boundaries. |
|
||||
| Holds | `docs/reports/deferred/758-fleet-config-deferrals.md` records M3-002, M4-002, M5-002, compatibility, and repository-structure boundaries. |
|
||||
|
||||
## Documentation completion checklist
|
||||
|
||||
|
||||
@@ -66,18 +66,18 @@ The contract rightly requires `pg_catalog, <mosaic_application_schema>` and reje
|
||||
|
||||
## Acceptance and threat traceability
|
||||
|
||||
| Requirement / threat | Review result | Evidence or blocking finding |
|
||||
| ----------------------------------------------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| K101-REQ-01 / AC-K101-01 split runtime/migration URLs | Partial | Role/DTO boundary is coherent; HIGH DDL-path finding requires all current commands to be closed. |
|
||||
| K101-REQ-02 / AC-K101-02 explicit migration/readiness | Blocked | HIGH ledger definition and HIGH DDL-bypass findings. |
|
||||
| K101-REQ-03 / AC-K101-03 least privilege, TLS, grants | Partial | Role model, default privileges, ledger read-only, TEMP/function checks are well specified (`KBN-101...:47-56,70-79`); HIGH TLS bootstrap and MEDIUM identifier constraints remain. |
|
||||
| K101-REQ-04 / AC-K101-04 immutable relations | Correctly deferred | KBN-101-09 after KBN-100 is the correct serial gate (`KBN-101...:58-66,115-118`); no synthetic-only certification claim found. |
|
||||
| K101-REQ-05 / AC-K101-05 N-1, secrets, rollback | Partial | No owner-runtime exception and rollback keeps migration URL out of Gateway (`:83-95`); deployable TLS and full command inventory are missing. |
|
||||
| K101-REQ-06 / AC-K101-07 KBN gates and DAG | Structurally sound | DAG is acyclic: 00→01/{03}; 02→06; 00/01/03→05; 00/04/05/06→07→08→KBN-100→09→KBN-105. KBN-100’s current branch contains docs-only baseline tracking, not schema implementation. |
|
||||
| T: runtime DDL / migration fallback | Blocked | HIGH finding 1. Current Gateway/storage, CLI, direct Drizzle scripts, and integration DDL require explicit closure. |
|
||||
| T: race/crash/readiness | Partial | Same-session nonblocking lock and replica-unready rules are present (`:34-38`); lock namespace remediation required. |
|
||||
| T: immutable evidence rewrite | Correctly staged | Explicit INSERT/SELECT-only matrix and RESTRICT retention are retained; proof is properly after table creation. |
|
||||
| T: secret leakage / TLS downgrade | Partial | Redaction and distinct Vault paths are specified (`:93-97`), but no server TLS/bootstrap implementation contract exists. |
|
||||
| Requirement / threat | Review result | Evidence or blocking finding |
|
||||
| --- | --- | --- |
|
||||
| K101-REQ-01 / AC-K101-01 split runtime/migration URLs | Partial | Role/DTO boundary is coherent; HIGH DDL-path finding requires all current commands to be closed. |
|
||||
| K101-REQ-02 / AC-K101-02 explicit migration/readiness | Blocked | HIGH ledger definition and HIGH DDL-bypass findings. |
|
||||
| K101-REQ-03 / AC-K101-03 least privilege, TLS, grants | Partial | Role model, default privileges, ledger read-only, TEMP/function checks are well specified (`KBN-101...:47-56,70-79`); HIGH TLS bootstrap and MEDIUM identifier constraints remain. |
|
||||
| K101-REQ-04 / AC-K101-04 immutable relations | Correctly deferred | KBN-101-09 after KBN-100 is the correct serial gate (`KBN-101...:58-66,115-118`); no synthetic-only certification claim found. |
|
||||
| K101-REQ-05 / AC-K101-05 N-1, secrets, rollback | Partial | No owner-runtime exception and rollback keeps migration URL out of Gateway (`:83-95`); deployable TLS and full command inventory are missing. |
|
||||
| K101-REQ-06 / AC-K101-07 KBN gates and DAG | Structurally sound | DAG is acyclic: 00→01/{03}; 02→06; 00/01/03→05; 00/04/05/06→07→08→KBN-100→09→KBN-105. KBN-100’s current branch contains docs-only baseline tracking, not schema implementation. |
|
||||
| T: runtime DDL / migration fallback | Blocked | HIGH finding 1. Current Gateway/storage, CLI, direct Drizzle scripts, and integration DDL require explicit closure. |
|
||||
| T: race/crash/readiness | Partial | Same-session nonblocking lock and replica-unready rules are present (`:34-38`); lock namespace remediation required. |
|
||||
| T: immutable evidence rewrite | Correctly staged | Explicit INSERT/SELECT-only matrix and RESTRICT retention are retained; proof is properly after table creation. |
|
||||
| T: secret leakage / TLS downgrade | Partial | Redaction and distinct Vault paths are specified (`:93-97`), but no server TLS/bootstrap implementation contract exists. |
|
||||
|
||||
## Unresolved assumptions
|
||||
|
||||
@@ -92,15 +92,15 @@ The contract rightly requires `pg_catalog, <mosaic_application_schema>` and reje
|
||||
|
||||
Read-only checks run in this review:
|
||||
|
||||
| Check | Result |
|
||||
| --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `git diff --check origin/main...da742ca2...` | PASS |
|
||||
| `pnpm exec prettier --check` on all seven changed docs | PASS |
|
||||
| `pnpm exec tsc --noEmit -p docs/native-kanban-sot/tsconfig.json` | PASS |
|
||||
| `docker compose -f docker-compose.yml config --quiet` (isolated test ports) | PASS |
|
||||
| `docker compose -f docker-compose.federated.yml --profile federated config --quiet` (isolated test ports) | PASS |
|
||||
| Static journal inspection | FAILS the required monotonic ordering premise: 0008 → 0009 `when` decreases; current runner documents skipping behavior. |
|
||||
| Static DDL-entrypoint inventory | Found direct Drizzle scripts, storage CLI shell-out, runtime extension/migration calls, fleet backlog migration, tier probe extension creation, and a direct-DLL federated integration test. |
|
||||
| Check | Result |
|
||||
| --- | --- |
|
||||
| `git diff --check origin/main...da742ca2...` | PASS |
|
||||
| `pnpm exec prettier --check` on all seven changed docs | PASS |
|
||||
| `pnpm exec tsc --noEmit -p docs/native-kanban-sot/tsconfig.json` | PASS |
|
||||
| `docker compose -f docker-compose.yml config --quiet` (isolated test ports) | PASS |
|
||||
| `docker compose -f docker-compose.federated.yml --profile federated config --quiet` (isolated test ports) | PASS |
|
||||
| Static journal inspection | FAILS the required monotonic ordering premise: 0008 → 0009 `when` decreases; current runner documents skipping behavior. |
|
||||
| Static DDL-entrypoint inventory | Found direct Drizzle scripts, storage CLI shell-out, runtime extension/migration calls, fleet backlog migration, tier probe extension creation, and a direct-DLL federated integration test. |
|
||||
|
||||
No live database, Vault, CI, deployment, issue, PR, or repository mutation was performed. The pass results validate documentation syntax/contract compilation and compose syntax only; they do **not** certify the proposed security behavior.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user