|
|
|
@@ -1,6 +1,12 @@
|
|
|
|
|
# PRD: Mosaic Stack
|
|
|
|
|
|
|
|
|
|
- Status: approved, version 1.17. Jason approved draft 0.4 unchanged as
|
|
|
|
|
- Status: approved, version 1.18. Jason approved the exact text in Q289.
|
|
|
|
|
- Version 1.18 adds disk-space governance, launch-capacity holds,
|
|
|
|
|
human-controlled retention rules, and the protected `data.delete.policy`
|
|
|
|
|
route. It preserves per-batch `data.delete` hard waits. Jason approved
|
|
|
|
|
the exact text at `e5400456` under REQ-WAIT-2: "1.18: yes" (DECISIONS
|
|
|
|
|
Q289, relayed by Mos in mos-2300). Q288 approved the recurring-rule principle.
|
|
|
|
|
- Prior approval history, through version 1.17: Jason approved draft 0.4 unchanged as
|
|
|
|
|
1.0 on 2026-10-05 (lead decision 61). They approved version 1.1, the
|
|
|
|
|
Organization requirements, in decision 03130d08-ddce-480d-a601-e59f64744fc3
|
|
|
|
|
on 2026-10-14. They approved version 1.2, the chief of staff, the
|
|
|
|
@@ -55,6 +61,16 @@
|
|
|
|
|
Q226 and Q234. It changes what Case 2 requirements allow, so Mos puts
|
|
|
|
|
the text to Jason as written, and it lands only after his yes (mos-1366,
|
|
|
|
|
Vikunja 570).
|
|
|
|
|
- Version 1.18 source, Jason's DECISIONS Q287, verbatim:
|
|
|
|
|
|
|
|
|
|
> All of the learnings from this drive space issue need to be integrated into Mosaic Stack. We need watchers, cleanups, enforcement tooling and agents to check for space waste, etc.
|
|
|
|
|
|
|
|
|
|
Jason's DECISIONS Q288, verbatim:
|
|
|
|
|
|
|
|
|
|
> The Stack may run a recurring cleanup under the approved rule that a user is able to revoke or change. It should be tunable in the system settings.
|
|
|
|
|
|
|
|
|
|
These rulings are the recorded rationale. Jason approved the mapped 1.18
|
|
|
|
|
text under REQ-WAIT-2 in Q289, relayed by Mos in mos-2300.
|
|
|
|
|
- Version 1.17 source: Jason's Q235, answering Q36: 'How about we see a
|
|
|
|
|
markdown file, we convert the markdown file to docx, then archive or
|
|
|
|
|
mark the markdown file as converted. The new standard for files in the
|
|
|
|
@@ -504,12 +520,61 @@ Added in version 1.7:
|
|
|
|
|
- An unknown key is refused, and so is a key set at a layer it isn't
|
|
|
|
|
allowed in.
|
|
|
|
|
- **REQ-VAR-2.** `~/.config/mosaic-dev/config.json` stays the only system
|
|
|
|
|
config, and nothing writes it automatically. A secret appears only as a
|
|
|
|
|
reference, either a file path or an environment variable name. Only
|
|
|
|
|
config, and nothing writes it automatically. Since version 1.18, only
|
|
|
|
|
an authorized human Console or CLI settings action outside an agent run
|
|
|
|
|
may write the disk settings under REQ-DISK-3 and REQ-DISK-4. No agent or
|
|
|
|
|
automatic writer may write them. Rule settings stay system-only. Revision
|
|
|
|
|
approvals and immutable inventories live in the decision and event stores,
|
|
|
|
|
keyed by revision ID, not a second system configuration. A secret appears
|
|
|
|
|
only as a reference, either a file path or an environment variable name. Only
|
|
|
|
|
the broker reads a secret's contents. It holds them in memory and
|
|
|
|
|
never logs or writes them. Everything else checks a referenced file
|
|
|
|
|
with `stat`.
|
|
|
|
|
|
|
|
|
|
#### Disk settings (proposed version 1.18)
|
|
|
|
|
|
|
|
|
|
All proposed keys below are human-only. Read access follows role grants. No agent-layer or environment override is allowed.
|
|
|
|
|
|
|
|
|
|
Use duration values, positive integer counts, bounded numeric percentages, and integer byte and inode floors. Path sets contain canonical paths.
|
|
|
|
|
|
|
|
|
|
For plain values, the most specific allowed layer wins. Limit floors merge by maximum and percentage thresholds by minimum. Sets merge by union. Required coverage cannot be removed.
|
|
|
|
|
|
|
|
|
|
| Key | Default | Allowed layers | Merge rule |
|
|
|
|
|
| --- | --- | --- | --- |
|
|
|
|
|
| `disk.coverage` | Required instance roots, with registered additions | System, business | Union |
|
|
|
|
|
| `disk.watch.interval` | 15 minutes | System, business | Most specific wins |
|
|
|
|
|
| `disk.watch.used_percent`, `disk.watch.inode_percent` | Breach at or above 85% | System, business | Minimum |
|
|
|
|
|
| `disk.watch.free_bytes` | 0 extra floor on other filesystems | System, business | Maximum |
|
|
|
|
|
| `disk.launch.free_bytes` | 2 GiB on each runtime temp, home, and workspace filesystem | System, business, project | Maximum |
|
|
|
|
|
| `disk.launch.free_inodes` | 1,024 on each launch filesystem with inode accounting | System, business, project | Maximum |
|
|
|
|
|
| `disk.watch.timeout` | 15 seconds per filesystem | System, business | Most specific wins |
|
|
|
|
|
| `disk.alert.repeat_interval`, `disk.alert.change_percent` | 6 hours or a 2-point increase | System, business | Most specific wins per key |
|
|
|
|
|
| `disk.alert.recovery_margin_percent` | 2 percentage points for byte-use and inode-use percentages | System, business | Most specific wins |
|
|
|
|
|
| `disk.alert.recovery_margin_bytes` | 2 GiB above each applicable byte floor | System, business | Most specific wins |
|
|
|
|
|
| `disk.alert.recovery_samples` | 2 consecutive valid samples meeting recovery margins | System, business | Most specific wins |
|
|
|
|
|
| `disk.alert.routing` | Runtime temp or byte-floor breach immediate, others daily digest | System, business | Most specific wins |
|
|
|
|
|
| `disk.monitor.stale_after` | 45 minutes since completion or first undelivered alert | System, business | Most specific wins |
|
|
|
|
|
| `disk.monitor.supervisor_interval` | 5 minutes | System | System value |
|
|
|
|
|
| `disk.monitor.watchdog_interval` | 5 minutes | System | System value |
|
|
|
|
|
| `disk.monitor.fallback` | Require a tested existing channel and independent writable destination at setup | System | System value |
|
|
|
|
|
| `disk.retention.policies` | Empty. Offer disabled daily scratch template, older than 48 hours | System only | System map keyed by policy ID, human-approved revisions only |
|
|
|
|
|
| `disk.paths.temporary`, `disk.paths.retained` | Installer instance roots, no operator path in product code | System, business | Union per key |
|
|
|
|
|
| `disk.audit.interval`, `disk.audit.timeout` | Weekly plus each new capacity incident, 180 seconds per root | System, business | Most specific wins per key |
|
|
|
|
|
| `disk.failure.unexplained_limit` | 3 failed attempts before investigation | System, business | Most specific wins |
|
|
|
|
|
| `disk.filesystem_overrides` | Empty typed map | System only | Exact filesystem entry replaces corresponding system base values before layer merging |
|
|
|
|
|
|
|
|
|
|
- Type `disk.filesystem_overrides` as a map keyed by instance host identity and resolved filesystem identity. Each entry may set watcher percentages, watcher free bytes, launch free bytes, and launch free inodes with the types above.
|
|
|
|
|
- Resolve all path aliases to that identity. Refuse unknown override fields, unmatched identities, and conflicting aliases. There are no separate path overrides.
|
|
|
|
|
- Watchers use system and business values only. They also apply system and business launch floors on registered launch filesystems. One filesystem has one effective watcher configuration and one incident per condition.
|
|
|
|
|
- Project floors apply only to that project's launch checks. A project's stricter floor cannot change shared watcher thresholds or create a second filesystem incident.
|
|
|
|
|
- Type routing as a condition-to-channel map, fallback as a channel and destination record, and policies as records defined by REQ-DISK-4. Routing merges as one plain value. Blocking hard waits always retain immediate delivery.
|
|
|
|
|
|
|
|
|
|
Two recovery samples resist brief swings. The 2 GiB launch floor and 1,024-inode floor reserve startup room on smaller instance disks. They are defaults, not guarantees of workload fit.
|
|
|
|
|
|
|
|
|
|
Validate positive durations and counts, bounded percentages, nonnegative extra byte floors, and positive launch floors. Reject recovery margins that make recovery impossible. Reject liveness deadlines shorter than a complete configured check, including supervisor and watchdog intervals.
|
|
|
|
|
|
|
|
|
|
Reject a temp root that contains, or sits inside, a retained root. Repeated audit proposals update existing work.
|
|
|
|
|
|
|
|
|
|
### Credentials
|
|
|
|
|
|
|
|
|
|
- **REQ-CRED-1.** Every role instance has its own token for each service
|
|
|
|
@@ -529,6 +594,11 @@ Added in version 1.7:
|
|
|
|
|
Since version 1.11, Gitea follows Q190: each agent seat gets its own
|
|
|
|
|
Gitea user through a grant (REQ-GRANT-1, REQ-GRANT-2), not a bot user
|
|
|
|
|
per role made by hand. Vikunja is unchanged.
|
|
|
|
|
|
|
|
|
|
Since version 1.18, each instance also has the protected disk-service
|
|
|
|
|
principal of REQ-DISK-12 with its own broker-held Vikunja bot. A human
|
|
|
|
|
creates its bot and token by hand from a runbook. This adds no automatic
|
|
|
|
|
account creation or role-decision authority.
|
|
|
|
|
- **REQ-CRED-2.** A session that finds only founder credentials stops.
|
|
|
|
|
|
|
|
|
|
Added in version 1.7:
|
|
|
|
@@ -557,6 +627,10 @@ Added in version 1.8 (Q188):
|
|
|
|
|
within-role still needs a decision for each use. Only a reviewed role
|
|
|
|
|
change adds an action to a definition. `host.sudo` routes under this
|
|
|
|
|
requirement.
|
|
|
|
|
|
|
|
|
|
Later remote privileged disk cleanup uses only the reviewed fixed helper
|
|
|
|
|
of REQ-DISK-6, with policy ID and candidate-list hash as its only inputs.
|
|
|
|
|
A raw deletion or shell prefix is never a grant. (Version 1.18.)
|
|
|
|
|
- **REQ-GRANT-1.** No agent creates or writes a grant. A grant request
|
|
|
|
|
follows the chain of command, and only the chief of staff raises it to
|
|
|
|
|
the user's inbox. Any other role that needs a grant for itself or for an
|
|
|
|
@@ -640,7 +714,10 @@ Added in version 1.8 (Q188):
|
|
|
|
|
- who resolved it;
|
|
|
|
|
- its timestamps.
|
|
|
|
|
|
|
|
|
|
A correction is a new row.
|
|
|
|
|
A correction is a new row. Since version 1.18, human-approved retention
|
|
|
|
|
revisions and their immutable inventories are keyed by revision ID in
|
|
|
|
|
the decision and event stores under REQ-DISK-4. A policy run binds to
|
|
|
|
|
its live approved revision, never a reused ordinary decision.
|
|
|
|
|
- **REQ-DEC-2.** Routing follows the decision's class and whether it
|
|
|
|
|
cites the project's spec (REQ-PROJ-2). Version 1.5 replaces the 1.0
|
|
|
|
|
text, which sent every gated decision to the human:
|
|
|
|
@@ -701,20 +778,24 @@ Added in version 1.8 (Q188).
|
|
|
|
|
the WebUI or the CLI. The chief of staff's organization writes
|
|
|
|
|
(REQ-ROLE-3) can't change it, and no agent can. Every change is logged
|
|
|
|
|
with who made it. A change applies to the next use, and a run already in
|
|
|
|
|
progress keeps no exemption.
|
|
|
|
|
progress keeps no exemption. Since version 1.18, manual mode for
|
|
|
|
|
`data.delete.policy` requires a fresh per-use PM decision before the
|
|
|
|
|
protected executor dispatches under REQ-DISK-5. Protection settings
|
|
|
|
|
remain human-only under REQ-DISK-3.
|
|
|
|
|
|
|
|
|
|
### Hard waits
|
|
|
|
|
|
|
|
|
|
Added in version 1.5 (Q167).
|
|
|
|
|
|
|
|
|
|
- **REQ-WAIT-1.** These are the hard waits. Each always goes to the
|
|
|
|
|
human, and each maps to actions in the closed vocabulary:
|
|
|
|
|
human, except the protected policy route of REQ-DISK-5 since version
|
|
|
|
|
1.18, and each maps to actions in the closed vocabulary:
|
|
|
|
|
|
|
|
|
|
| Jason's wait | Actions |
|
|
|
|
|
| --- | --- |
|
|
|
|
|
| Spending money | `spend` |
|
|
|
|
|
| Deleting data | `data.delete`, new in 1.5 |
|
|
|
|
|
| Anything irreversible | `data.delete`, `git.push.protected` and REQ-WAIT-3 |
|
|
|
|
|
| Deleting data | `data.delete`, new in 1.5, and `data.delete.policy`, routed under REQ-DISK-5 since 1.18 |
|
|
|
|
|
| Anything irreversible | `data.delete`, `data.delete.policy` under REQ-DISK-5, `git.push.protected` and REQ-WAIT-3 |
|
|
|
|
|
| New internet exposure | `network.expose`, new in 1.5: a listener, port, tunnel, DNS record or proxy route reachable from outside the host. `deploy` stays a hard wait too. |
|
|
|
|
|
| New external accounts | `account.create`, new in 1.5, and `credential.mint` |
|
|
|
|
|
| Messages to people outside the fleet | `message.external` |
|
|
|
|
@@ -751,6 +832,23 @@ Added in version 1.5 (Q167).
|
|
|
|
|
commit by that agent's own Gitea account with a trailer naming the
|
|
|
|
|
agent, and the user sees a notice for it and can revert it.
|
|
|
|
|
|
|
|
|
|
`data.delete.policy` was added as a hard wait and routes under
|
|
|
|
|
REQ-DISK-5 since version 1.18.
|
|
|
|
|
|
|
|
|
|
#### Disk hard waits (proposed version 1.18)
|
|
|
|
|
|
|
|
|
|
- DISK-H1. Out-of-policy deletion requires the PM's exact-batch human approval and single-use consume. `data.delete` stays always gated and never enters a role grant.
|
|
|
|
|
- DISK-H2. Policy creation, change, enablement, and revocation require an authorized human Console or CLI session. The approved revision binds scope and executor. Agents cannot approve, change, enable, or revoke a rule.
|
|
|
|
|
- DISK-H3. Root access follows REQ-CRED-4 and never removes DISK-H1 or DISK-H2. Existing spending, exposure, account, and external-message hard waits remain.
|
|
|
|
|
- DISK-H4. Protection settings follow REQ-DEC-3 and REQ-TRUST-2. Granted read-only checks and reporting need no per-run approval.
|
|
|
|
|
|
|
|
|
|
Keep `data.delete` on the broker and vocabulary always-gated lists. Add
|
|
|
|
|
`data.delete.policy` to both lists with a protected-executor route requiring
|
|
|
|
|
a live human-approved revision. Every other caller is refused. No role file
|
|
|
|
|
may grant either action. Update the reviewed vocabulary and broker together
|
|
|
|
|
under REQ-WAIT-2 only after Jason approves version 1.18. Never reuse a
|
|
|
|
|
consumed ordinary decision as standing permission.
|
|
|
|
|
|
|
|
|
|
### Messages
|
|
|
|
|
|
|
|
|
|
- **REQ-MSG-1.** Messages are addressed to a role. They are append-only
|
|
|
|
@@ -772,7 +870,11 @@ Added in version 1.5 (Q167).
|
|
|
|
|
- **REQ-TASK-1.** Tasks live in Vikunja, reached through `/api/v2` with a
|
|
|
|
|
bot token for each role. Each task cites a requirement id. Each task
|
|
|
|
|
field has one writing role, listed in the slice 1 brief's field table,
|
|
|
|
|
and the assigned role writes the task's state. Vikunja's token scopes
|
|
|
|
|
and the assigned role writes the task's state. Since version 1.18, the
|
|
|
|
|
scoped disk-service principal in REQ-DISK-12 may initialize incident
|
|
|
|
|
fields from a PM-approved template and update only its exclusive fields
|
|
|
|
|
in the extended slice 1 brief table. It gains no role-decision authority
|
|
|
|
|
and never writes later task state or closure. Vikunja's token scopes
|
|
|
|
|
cover whole route groups, so the broker's verbs enforce this, not the
|
|
|
|
|
tokens. A person's edits come in as events.
|
|
|
|
|
- **REQ-TASK-2.** Polling is the source of truth. Every 30 seconds the
|
|
|
|
@@ -888,6 +990,10 @@ Added in version 1.7:
|
|
|
|
|
- see the decision inbox and resolve decisions;
|
|
|
|
|
- see tasks and agents;
|
|
|
|
|
- follow the trail of any piece of work.
|
|
|
|
|
Since version 1.18, CLI and Console also show disk coverage, effective
|
|
|
|
|
settings and source layers, incidents, cleanup proposals and capacity
|
|
|
|
|
refusal reasons. Only authorized humans outside an agent run control
|
|
|
|
|
disk settings and policy revisions (REQ-DISK-3, REQ-DISK-4).
|
|
|
|
|
- **REQ-CLI-2.** The assistant session that `mosaic` talks to is one the stack
|
|
|
|
|
launches and owns, running Pi or Claude Code without a window. The
|
|
|
|
|
product doesn't depend on T3. (Round 2, answer 5A.)
|
|
|
|
@@ -898,7 +1004,9 @@ Added in version 1.7:
|
|
|
|
|
and names projects and threads there without a terminal. Its Settings
|
|
|
|
|
view shows every agent limit, the usage counted against each, and the
|
|
|
|
|
model each role instance runs, and lets the user change them
|
|
|
|
|
(REQ-LIMIT-1 to REQ-LIMIT-3).
|
|
|
|
|
(REQ-LIMIT-1 to REQ-LIMIT-3). Since version 1.18 it also exposes the
|
|
|
|
|
disk views and human policy controls specified in REQ-CLI-1 and
|
|
|
|
|
REQ-DISK-3 through REQ-DISK-5.
|
|
|
|
|
- **REQ-WEB-2.** The Console resolves an open decision with one button
|
|
|
|
|
per option, only for a human it signed in itself, recorded via=console.
|
|
|
|
|
(Version 1.9, decision 00ed58e2, Q175 and Q203.)
|
|
|
|
@@ -935,6 +1043,11 @@ Added in version 1.7:
|
|
|
|
|
idle thread holds no session and counts against none. The stack starts
|
|
|
|
|
the chief of staff itself. (Round 2, answer 6A; Q147; Q150.)
|
|
|
|
|
|
|
|
|
|
Since version 1.18, every role launch, including assistant and chief
|
|
|
|
|
startup, also passes the fresh capacity preflight in REQ-DISK-2. The
|
|
|
|
|
Stack launcher owns host-capacity holds and releases, and retries pending
|
|
|
|
|
launches on verified recovery. It never releases quota or other holds.
|
|
|
|
|
|
|
|
|
|
Added in version 1.2. Jason, Q150, verbatim: "No hard cap on agent
|
|
|
|
|
limits. All tunable. Agent limit: A parallel execution limit arbitrarily
|
|
|
|
|
set by the user or COS. This limit can apply to: overall executing agent
|
|
|
|
@@ -1067,13 +1180,132 @@ Added in version 1.3 (Q155).
|
|
|
|
|
|
|
|
|
|
Hooks only refuse early and log, and no document may call them
|
|
|
|
|
enforcement. A probe run against the live harnesses must pass before any
|
|
|
|
|
build relies on a block.
|
|
|
|
|
build relies on a block. Since version 1.18, durable registration and
|
|
|
|
|
the launches requiring it also pass REQ-DISK-7's temp-root checks on
|
|
|
|
|
each supported harness. A failed live registration probe refuses them.
|
|
|
|
|
Arbitrary shell-write prevention and broader sandbox enforcement are
|
|
|
|
|
later work.
|
|
|
|
|
|
|
|
|
|
### Events
|
|
|
|
|
|
|
|
|
|
- **REQ-EVT-1.** Every step in slice 1 emits an event to the append-only
|
|
|
|
|
store. Measures are computed from events, never from tagging chat
|
|
|
|
|
messages by hand.
|
|
|
|
|
messages by hand. Since version 1.18, disk samples, incidents, policy
|
|
|
|
|
revisions, cleanup and temp-path events follow REQ-DISK-14. They remain
|
|
|
|
|
append-only, with retained reports outside temp and storage failure
|
|
|
|
|
handling under REQ-DISK-10.
|
|
|
|
|
|
|
|
|
|
### Disk-space governance
|
|
|
|
|
|
|
|
|
|
Proposed in version 1.18.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-1.** Coverage.
|
|
|
|
|
- Register managed runtime temp, homes, workspaces, evidence, application state, logs, and backup paths. Show paths outside the instance's coverage explicitly.
|
|
|
|
|
- Resolve aliases to filesystem identities and group them into one capacity incident with every affected path. Missing paths, changed mounts, and denied reads are unknown, never healthy. Remote-host monitoring is outside v1.
|
|
|
|
|
- Reconcile coverage at installation, onboarding, and path changes. Warn when runtime temp shares a filesystem with retained or bulk paths.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-2.** Watchers and launch preflight.
|
|
|
|
|
- A deterministic boot service measures available bytes, used percentage, and inode use at the configured interval without an agent turn. One path failure cannot stop other checks.
|
|
|
|
|
- Compute used percentage as `ceil(100*used/(used+avail))`, matching `df -P`. Zero byte denominators or failed measurements produce unknown status with a reason. Filesystems without inode accounting report inode checks as not applicable.
|
|
|
|
|
- Store host, paths, filesystem identity, UTC sample time, measurements, effective thresholds, and result.
|
|
|
|
|
- Before every role launch, including assistant and chief-of-staff startup, freshly check the filesystems holding the resolved harness `TMPDIR`, home, and workspace. Deduplicate shared filesystems. Apply a nonzero default byte floor to every registered runtime temp filesystem.
|
|
|
|
|
- Refuse launch below the effective byte floor or, where inode accounting exists, the free-inode floor. Byte-use and inode-use percentages trigger alerts only. Unknown required capacity refuses launch with a distinct unverified-capacity reason.
|
|
|
|
|
- Log `host.capacity` as the refusal reason with the filesystem, measurement, and failed check, like a REQ-LAUNCH-1 limit refusal.
|
|
|
|
|
- The Stack launcher owns the host-capacity hold and release, even when chief-of-staff startup is refused. Refused threads show the reason in CLI and Console. Watcher and liveness services run independently of role launches.
|
|
|
|
|
- On verified recovery, the launcher releases only the capacity hold and retries pending launches, including chief-of-staff startup. All other launch limits still apply. A later write can still fail, so retain REQ-DISK-11 classification.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-3.** Settings.
|
|
|
|
|
- Declare typed keys and allowed layers under REQ-VAR-1. Show effective values and source layers in Console Settings and CLI.
|
|
|
|
|
- Protection settings are human-only under Q222, REQ-DEC-3, and the REQ-TRUST-2 precedent. Chief-of-staff organization writes and environment overrides cannot change them.
|
|
|
|
|
- Refuse unknown keys, invalid values, unauthorized writers, and unauthorized layers. Keep the last valid value or declared first-setup default. Record the refusal and notify the owner.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-4.** Cleanup policies.
|
|
|
|
|
- Start with no enabled policy. Store rule settings only at the system layer in the existing `config.json` under REQ-VAR-2.
|
|
|
|
|
- REQ-VAR-2 permits writes only from an authorized human Console or CLI settings action outside an agent run. No automatic writer or agent may write these settings.
|
|
|
|
|
- Store revision approvals and immutable inventories in the decision and event stores, keyed by revision ID. These records are not a second system configuration.
|
|
|
|
|
- Each revision names host, canonical root, file classes, age calculation, minimum age, schedule, exclusions, human owner, protected executor, and bounded scope. Attach a dry-run inventory.
|
|
|
|
|
- An authorized human approves, changes, enables, or revokes the revision outside an agent run. The human's confirmed change is fresh approval of the exact new revision.
|
|
|
|
|
- Agents cannot approve, change, enable, or revoke any rule. Revocation stops the next deletion, including remaining items in a running batch.
|
|
|
|
|
- Ownership, cache names, disk pressure, and audit advice grant no authority. Q286 is not a global default approval or automatic import.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-5.** Cleanup execution.
|
|
|
|
|
- The protected executor uses `data.delete.policy` only for candidates covered by a live approved revision. Bind every run to that revision and record it.
|
|
|
|
|
- Before each deletion, recheck revision, canonical path and mount identity, ownership, exclusions, active use, and candidate identity. Refuse symlink escapes and changed or uncertain candidates. Serialize execution per scope.
|
|
|
|
|
- Preserve protected evidence, source, user data, credentials, and active work. Record skipped items and reasons.
|
|
|
|
|
- Record proposed allocated bytes and available bytes before and after separately. Do not promise that allocated bytes will become free space. Partial or failed runs create owned follow-up work and never report success.
|
|
|
|
|
- Outside an enabled rule, the PM raises and consumes one exact-batch `data.delete` decision under REQ-DEC-5. The service cannot raise or consume that role-bound approval.
|
|
|
|
|
- For that batch, the protected executor accepts only a one-shot dispatch bound to the decision ID, the PM's consumed-action record, and the approved candidate hash. It refuses missing or mismatched bindings and replay.
|
|
|
|
|
- If a human puts `data.delete.policy` in manual mode under REQ-TRUST-2, the PM raises and consumes a fresh per-use decision before dispatch. The service gets no exemption.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-6.** Ownership and privilege.
|
|
|
|
|
- Apply approval checks to agent-owned and root-owned data. Skip inaccessible files and report their measured size or unknown size. Never try another user's credentials, chmod, chown, or implicit sudo.
|
|
|
|
|
- On the instance's own host, the service user stays without sudo. Root-owned candidates always become a human task.
|
|
|
|
|
- Later remote privileged cleanup under REQ-CRED-4 uses a reviewed fixed helper. Its only inputs are a policy ID and candidate-list hash. It loads the approved revision and immutable inventory itself, verifies both, and refuses extra arguments or paths.
|
|
|
|
|
- Never grant raw `rm` or a shell prefix. An argv prefix can admit appended paths. A helper grant supplies access, never deletion authority.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-7.** Temp boundaries.
|
|
|
|
|
- Declare temporary and retained roots. At durable registration, the broker refuses an artifact, repository, cited evidence path, collector registration, reusable launched-script path, or retained log destination under temp, including symlink-resolved paths.
|
|
|
|
|
- Add proposed broker verbs `artifact.register`, `repository.register`, `evidence.register`, `collector.register`, `script.register`, and `log.register`. Each requires an artifact class and canonical destination. Launch manifests carry the same fields for reusable scripts and retained logs.
|
|
|
|
|
- Refuse these registrations and launches that require them on every supported harness if the live registration probe fails. Hooks and CI only refuse early under REQ-HARN-2.
|
|
|
|
|
- Filesystem mounts cannot distinguish durable work from scratch. Watchers or audits detect existing git repositories and executables under temp and open migration tasks. Arbitrary shell writes are not claimed as prevented in v1.
|
|
|
|
|
- Migration preserves hashes and cited references before cleanup becomes eligible. Ephemeral scratch remains allowed. Sandbox enforcement beyond registration is later work.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-8.** Waste audits.
|
|
|
|
|
- Run scheduled and pressure-triggered read-only audits within declared path grants. Return paths, owner, allocated size, UTC measurement time, active-use checks, retention risk, and a proven reinstall or recovery procedure.
|
|
|
|
|
- Cover caches, unused toolchains, and dependencies. For every proposed candidate, prove its recovery procedure for that class. Missing proof means keep.
|
|
|
|
|
- For caches, require a declared regeneration command and verified retained inputs. For toolchains, require the exact version, an available installation source, and a declared reinstall command. Active toolchains remain protected.
|
|
|
|
|
- For `node_modules`, require an adjacent manifest and lockfile, matching package manager, and checks for local changes or linked dependencies. Record the exact locked-install command and available package sources. Local or linked dependencies need separate recovery proof.
|
|
|
|
|
- Mark permission failures, timeouts, stale remote refs, hard links, and sparse files as estimate limits. Do not sum overlapping scans. Flag files under agent temp roots owned by another user.
|
|
|
|
|
- Do not read credential contents, install, prune, fetch, delete, or approve the proposal. Old names and apparent duplicates prove no waste.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-9.** Alerts and recovery.
|
|
|
|
|
- Ensure one open Vikunja task per instance, host, filesystem, and condition. Use monitor identity for monitor failures. Cite the requirement, project, PM, paths, measurements, and needed action.
|
|
|
|
|
- A breach on a filesystem holding runtime temp, or below its effective byte floor, goes immediately to CLI inbox and the existing Discord connector. Other breaches go to the daily digest. Routing is a human setting. Blocking hard waits retain REQ-DEC-4 immediate delivery.
|
|
|
|
|
- Reconcile before creation and serialize incident keys. Retries after restart or lost responses converge on one task. Repeat observations update service fields. Comments follow the time and percentage-change settings. Condition changes and recovery bypass the throttle.
|
|
|
|
|
- Recovery requires consecutive valid samples strictly below each percentage threshold minus its margin, and at least each byte floor plus its byte margin. Where inode accounting exists, free inodes must meet the launch floor. Inode checks marked not applicable do not block recovery. Unknown samples reset the count.
|
|
|
|
|
- Emit one recovery event and comment. The Stack launcher releases the host-capacity launch hold on recovery but never a quota hold. The assigned role verifies task closure. Rebreach reuses an open task or creates a new incident after closure.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-10.** Liveness and storage failure.
|
|
|
|
|
- A separate local supervisor checks completed watcher samples and delivery acknowledgements.
|
|
|
|
|
- The installer configures an independent Stack watchdog timer that checks the supervisor's last successful check against the liveness deadline. It alerts through the tested fallback when the supervisor stalls or stops. No agent turn or external heartbeat is required.
|
|
|
|
|
- Cross-host supervision is later work, so v1 cannot claim detection during complete host loss.
|
|
|
|
|
- Missed sample or supervisor deadlines, corrupt state, stalled runs, credential failure, task delivery failure, and event-write failure are monitor failures.
|
|
|
|
|
- When a store fails, retain pending notices on a separate writable destination and use a tested existing channel. Never depend on writes to the full filesystem. Replay with stable IDs after recovery.
|
|
|
|
|
- Apply that rule to stored events and audit reports too. If no writable destination exists, report the storage failure through the fallback and mark the report incomplete. Never claim it was stored.
|
|
|
|
|
- Installation cannot claim monitored coverage without a tested local supervisor, independent watchdog timer, and fallback.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-11.** Failure classification.
|
|
|
|
|
- Distinguish host capacity, permission, authentication, measured quota hold, and unknown provider failure. `ENOSPC` cites host and filesystem. It never becomes REQ-LIMIT-2 quota exhaustion or a quota-reset wait.
|
|
|
|
|
- Generic provider errors stay unknown until evidence distinguishes them. Check host health and authentication before the chief of staff resumes work within existing limits.
|
|
|
|
|
- At the configurable unexplained-failure count, stop automatic retries for that operation and create investigation work. Disk recovery does not clear authentication or quota failures.
|
|
|
|
|
|
|
|
|
|
#### Disk roles, tasks, and events
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-12.** Roles and protected services.
|
|
|
|
|
- The chief of staff launches audits within REQ-LAUNCH-1. The PM owns triage, follow-up, and per-batch decisions. The assistant explains notices under REQ-ASSIST-1.
|
|
|
|
|
- Watcher, supervisor, watchdog, and cleanup executor are deterministic processes, not role instances. Add one protected disk-service principal per Stack instance with its own broker-held Vikunja bot.
|
|
|
|
|
- A human creates the Vikunja bot and token by hand from a runbook under REQ-CRED-1. No automatic account creation is added. REQ-TASK-1 admits this scoped service principal without granting role-decision authority.
|
|
|
|
|
- Policy runs bind to the approved policy revision and service principal, not a consumed REQ-DEC-5 approval. Ordinary decisions keep their role, thread, and single-use binding.
|
|
|
|
|
- The audit worker gets only typed read-only tools: allocated-size scans, filesystem `stat`, `/proc` active-use checks, `git --no-optional-locks status --porcelain`, and manifest or lockfile checks. Each tool enforces path grants and bounds. It gets no shell, write, deletion, privilege, or credential-content access.
|
|
|
|
|
|
|
|
|
|
Extend the slice 1 brief's field table with these exclusive writers. Incident creation initializes fields from a PM-approved template. Later edits follow the table. Keep REQ-TASK-1's assigned-role state writer.
|
|
|
|
|
|
|
|
|
|
| Task fields or operation | Writer |
|
|
|
|
|
| --- | --- |
|
|
|
|
|
| Later incident key, measurements, last observation, recovery status, and service comments | Instance disk-service principal through scoped broker verbs |
|
|
|
|
|
| Initial incident fields, including identity, measurements, project, assignee, and initial state | Disk-service create verb using a PM-approved template |
|
|
|
|
|
| Later title, description, project, assignee, and priority edits | PM through existing task verbs |
|
|
|
|
|
| Later task state and closure | Assigned role through existing task verbs under REQ-TASK-1 |
|
|
|
|
|
| Audit result record and cited report | Audit worker through report-only broker verb |
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-13.** Tasks.
|
|
|
|
|
- Every incident, audit proposal, migration, inaccessible cleanup, or monitor repair is owned Vikunja work citing its requirement. Reuse matching tasks and existing broker verbs.
|
|
|
|
|
- Human decisions link their task in the existing inbox. A daily digest never replaces a blocking hard-wait notification.
|
|
|
|
|
|
|
|
|
|
- **REQ-DISK-14.** Events.
|
|
|
|
|
- Extend REQ-EVT-1 with typed samples, breaches, launch refusals, recoveries, monitor failures, audit results, policy approvals, changes, revocations, cleanup attempts and results, and temp-path refusals.
|
|
|
|
|
- Record host, paths, filesystem, actor, task, decision or policy revision, UTC time, and outcome as applicable. Never include credentials or file contents.
|
|
|
|
|
- Retain events and approved reports outside temp under REQ-DISK-10 storage handling. Deleting them needs its own approved rule. Event records remain append-only under REQ-EVT-1.
|
|
|
|
|
|
|
|
|
|
### Organizations
|
|
|
|
|
|
|
|
|
@@ -1536,6 +1768,11 @@ Added in version 1.11 (Q187, Q189, Q211):
|
|
|
|
|
- Both v1 profiles enable the Console unit, so the Console starts at
|
|
|
|
|
install and at every boot (Q189). dragon-lin is unchanged.
|
|
|
|
|
- The container-based install comes after v1.
|
|
|
|
|
- Since version 1.18, register the instance's managed roots and warn
|
|
|
|
|
when runtime temp shares retained or bulk storage. Test the local
|
|
|
|
|
supervisor, independent watchdog timer and fallback before claiming
|
|
|
|
|
monitored coverage. Install and upgrade enable no deletion policies
|
|
|
|
|
(REQ-DISK-1, REQ-DISK-4, REQ-DISK-10).
|
|
|
|
|
|
|
|
|
|
## Acceptance criteria and success measures
|
|
|
|
|
|
|
|
|
@@ -1556,6 +1793,34 @@ both instances are installed and handle their cases: Case 1, the
|
|
|
|
|
software factory, and Case 2, the creative writing hub. 2026-10-27 is a
|
|
|
|
|
latest-by date and a hard target (Q176).
|
|
|
|
|
|
|
|
|
|
### Disk acceptance (proposed version 1.18)
|
|
|
|
|
|
|
|
|
|
DISK-AC1 through DISK-AC9 gate DISK-M1. DISK-AC10 is later and does not
|
|
|
|
|
gate that slice.
|
|
|
|
|
|
|
|
|
|
- DISK-AC1. On two disposable instance hosts, cover separate and shared filesystems, temp, homes, and retained roots. Changed mounts, denied reads, and missing paths produce unknown status without suppressing other checks. Installer warns when runtime temp shares retained or bulk storage.
|
|
|
|
|
- DISK-AC2. Verify capacity checks and launch recovery.
|
|
|
|
|
- Check 85% and just below, byte-floor equality and one byte below, free-inode floors, and typed filesystem overrides. Percentage-only byte and inode alerts permit launch.
|
|
|
|
|
- A filesystem without inode accounting reports not applicable and passes inode checks. A failed required measurement reports unknown and refuses launch.
|
|
|
|
|
- Fill the runtime temp filesystem. Refuse launch with reason `host.capacity`, never quota. The Stack launcher holds that host's launches, including chief-of-staff and assistant startup.
|
|
|
|
|
- Repeat for home and workspace. Recovery releases only the capacity hold and retries pending chief-of-staff startup. Refused threads show the reason in CLI and Console.
|
|
|
|
|
- Console and CLI show identical effective settings. Unauthorized setting writes fail with events. Check system override resolution and business merges. Project floors affect only that project's launches.
|
|
|
|
|
- DISK-AC3. Concurrency, restart, corrupt local state, and lost task-create replies converge on one open task. Swing usage between 84% and 85%. It never recovers at those values. With defaults, 83% also fails recovery and two samples at 82% recover if byte and inode margins pass. Check the byte margin, comment throttle, rebreach, and duplicate-free replay.
|
|
|
|
|
- DISK-AC4. Verify liveness and storage failures.
|
|
|
|
|
- Stop or stall the watcher. Deny credentials, break task delivery, and fill local state and report filesystems. The local supervisor detects watcher failures within its deadline.
|
|
|
|
|
- Stop or stall the supervisor. Verify the independent watchdog timer alerts through the fallback within its deadline.
|
|
|
|
|
- The fallback works without writes to full storage. Reconcile pending tasks, events, and partial reports after recovery.
|
|
|
|
|
- DISK-AC5. Audits and dry runs delete nothing. Policy fixtures cover age boundaries, exclusions, changed revisions, revocation during a batch, ownership, races, and symlink escapes. Root-owned candidates become human tasks. PM one-shot approval cannot be consumed by the service or twice. Manual mode gates each policy run. No production deletion is needed.
|
|
|
|
|
- DISK-AC6. On each supported v1 harness, refuse durable artifact, repository, evidence, collector, reusable script, and log registrations under temp, including symlink paths. Ephemeral scratch succeeds. A discovered git repo or executable under temp creates migration work. Retained migration preserves hashes and citations. Hooks alone cannot pass.
|
|
|
|
|
- DISK-AC7. Verify read-only audits and recovery proof.
|
|
|
|
|
- Use only REQ-DISK-12's fixed read-only tool set against caches, active toolchains, sparse disks, mail, changed repos, and dependencies with and without lockfiles.
|
|
|
|
|
- Include hard links, unreadable trees, and another user's temp files. Verify the git index is unchanged.
|
|
|
|
|
- Check per-class regeneration or reinstall proof, retained inputs, exact versions, locked installs, and unavailable sources. Report sizes and recovery procedures only where proven.
|
|
|
|
|
- Protected and uncertain data remain intact.
|
|
|
|
|
- DISK-AC8. Inject disk, permission, expired-authentication, measured-quota, and generic-provider failures. Keep classifications distinct. The configured unexplained-failure count stops automatic retries and creates investigation work. Recovery never clears an unrelated hold.
|
|
|
|
|
- DISK-AC9. Trace v1 runs in CLI and Console through requirements, task field ownership, events, human proof, policy revision, and result. Verify separate service identities on both instances, boot persistence without an agent, and no newly enabled policies after install or upgrade. Do not claim cross-host liveness or arbitrary-shell enforcement.
|
|
|
|
|
- DISK-AC10. Later remote privileged helper acceptance rejects extra paths, wrong hashes, and changed inventories. This criterion does not gate DISK-M1.
|
|
|
|
|
|
|
|
|
|
## Technical considerations
|
|
|
|
|
|
|
|
|
|
- Vikunja v2.7.0 is AGPL-3.0. Its API tokens can't create users or mint
|
|
|
|
@@ -2146,6 +2411,13 @@ latest-by date and a hard target (Q176).
|
|
|
|
|
|
|
|
|
|
## Milestones
|
|
|
|
|
|
|
|
|
|
### DISK-M1: disk-space governance
|
|
|
|
|
|
|
|
|
|
- DISK-M1 lands as version 1.18, which Jason approves under REQ-WAIT-2.
|
|
|
|
|
- v1 includes REQ-DISK-1, 2, 3, 8, 9, and 11, plus REQ-DISK-4 and 5 dry runs and Q288 policy execution.
|
|
|
|
|
- v1 includes the supporting ownership, registration checks, service identity, tasks, events, local supervisor, and independent watchdog timer defined above. DISK-AC1 through DISK-AC9 gate this slice.
|
|
|
|
|
- Cross-host supervision, remote privileged execution, and sandbox-level temp enforcement follow later. DISK-AC10 and those later capabilities do not gate DISK-M1.
|
|
|
|
|
|
|
|
|
|
Slice 1, in the order on the foundation direction page. The slice 1 brief
|
|
|
|
|
maps each step to requirement ids. CHAT-03's Gate E demonstration happens
|
|
|
|
|
during the slice 1 WebUI step, not separately (round 3, 7B).
|