Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/phase1-conformance.md
Original file line number Diff line number Diff line change
Expand Up @@ -1366,8 +1366,9 @@ The later SDK validator repin must use these exact committed file bytes:
| `scripts/phase1-windows-supervisor-build.sh` | 4,646 | `713a9e0282887ade3e243b5ba175794d74cdb02c28c38dcd41491c9505812770` |
| `scripts/phase1-windows-supervisor-install.ps1` | 1,743 | `2baab275f0bb6789884cded5f6185d00bfa5348b9e7c3ad1e5575353639101d5` |
| `scripts/windows-job-supervisor.cs` | 305,876 | `b034c6dd3c7af0724733259a1257cf6b2885c97ee08b3f9b1e2bba0abca9c3a1` |
| `scripts/windows-job-supervisor.test.ps1` | 177,716 | `a3b67a5b6130bc695ebd15cbf55718b40bd594409106e106b70b50c8840b3ffe` |
| `scripts/windows-job-supervisor.test.ps1` | 177,785 | `c0044f2ba955ff901fcbee3568a3dc081e590a5f880c0bb00fc4d2eedf2a3cf1` |
| `scripts/windows-quota-diagnostics.test.ps1` | 13,409 | `2594ddf573f7642eea7e050382dcc523daa5b477852d3db774b570328502a2e8` |
| `scripts/windows-owner-directory-quota.test.ps1` | 11,176 | `23b0b5106c5d50676622bf74238e465a80c5a6a9d017275d067263673d9ceecb` |
| `scripts/windows-identity-cleanup-diagnostics.test.ps1` | 5,324 | `f0dd69a9aadc6ca662fc7d33091986f40771d6ce3c10a57cda2e73f70c0e0417` |
| `scripts/windows-process-sid-diagnostics.cs` | 4,054 | `cd4b1c16a759ce4e63b87c82c4be0dbee9c0b48e9bfd3851eb966c303918e1a2` |
| `scripts/windows-process-sid-diagnostics.test.ps1` | 7,316 | `c83e2d63355fb95c8220045115a3b8106b7507b7132d235ad74eb0283f6c481f` |
Expand Down
51 changes: 50 additions & 1 deletion docs/roadmap.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,55 @@
# Delivery roadmap and consolidation audit

## Consolidation checkpoint, 2026-09-10 UTC
## Consolidation checkpoint, 2026-09-11 UTC

This checkpoint supersedes the pending landing and validation claims in the
historical snapshots below. The latest terminal protected attempt is
[34611963297](https://github.com/OpenCoven/chat/actions/runs/34611963297), using
Chat producer `37e6984d83835f8994392d35d28fc98813746716` and SDK validator
`7f53b74c1c2be2719c87a1c0592d1c13a6a641cf`. Both validator scopes matched that
revision. Linux and macOS passed; each retained record passed independent ZIP
digest, SDK parser/scanner, exact source identity, Cave timing, and ordered
110 Cave / 46 SDK / 41 Chat assertion checks.

Windows failed with bounded quota-monitor context:

```text
access-denied; root=harness-execution-aggregate; operation=directory-enumeration
```

Cleanup separately reported
`root-delete:win32-3,root-survived:invalid-operation`. Artifact validation,
attestation, and aggregation were skipped. This establishes neither quota
exhaustion nor the identity of the denied descendant.

| Work | Delivered evidence | Remaining work |
| --- | --- | --- |
| Frozen Linux backport adoption | Chat #210 and the prepared #207–#209 follow-ups landed. The production backport remains frozen at `0da8c4749f57e63601b29d66032f80c9bbac1cb5`; subsequent harness bindings retain the reviewed source ancestry. | [#188](https://github.com/OpenCoven/chat/issues/188) remains open for complete protected acceptance and advisory reconciliation. |
| Windows staging and diagnostics | Coven #988 and Chat #211 landed. Chat #216 adds bounded cleanup categories; #218 adds quota-root/operation context. All ten final #218 CI jobs passed, including native Windows tests. | Protected status-staging success remains unproven. [#219](https://github.com/OpenCoven/chat/issues/219) owns the quota enumeration repair and separate cleanup investigation. #211 review-thread disposition remains unverified. |
| Native quota reproduction | [Draft #220](https://github.com/OpenCoven/chat/pull/220) adds an isolated-owner directory fixture with readable and byte-overflow controls. See [the reproduction contract](windows-quota-reproduction.md). | Inspect native execution before selecting a repair. A matching fixture signature does not identify the protected run's denied descendant. |
| SDK binding | [SDK #204](https://github.com/OpenCoven/sdk/pull/204) landed at `7f53b74c1c2be2719c87a1c0592d1c13a6a641cf`, binding the exact #218 producer/workflow/bootstrap bytes. Both scopes were rotated and read back before the protected attempt. | Rebind any subsequent governed source change. [SDK #38](https://github.com/OpenCoven/sdk/issues/38) and the final release gate remain open. |
| Process-identity investigation | Chat #207's bounded test-only diagnostics landed. | [#206](https://github.com/OpenCoven/chat/issues/206) still requires causal evidence; later successful jobs do not classify its original failure. |

Diagnostic [#217](https://github.com/OpenCoven/chat/issues/217) and Bead
`cave-k0aqq.1` are complete on verified protected root/operation disclosure.
Repair Bead `cave-k0aqq.2` is active. The root Bead `cave-k0aqq`, final gate
`cave-ilh1h`, and authorized Teamwork root retain the outstanding release work.

The branch audit inspected 32 previously unattached Chat/SDK branches: 21 have
exact trees retained by merged commits in fetched main. Two additional branches
have no unmatched non-merge patches; that is weaker than complete delivery
proof. SDK PR #90 already delivered the canonicalize change; its local repair
branch's older dependency lock is not missing implementation to restore.
Alternate and unmatched histories still need individual disposition.

No branches or worktrees were removed in this checkpoint. Exact-tree retention
does not establish retirement of active or reserved ownership. Preserve dirty,
active, and ambiguous work, including Chat #214 and parked #86. The minimum
working set remains unestablished. Machine-readable delivery, branch, and
protected-run receipts remain in the external
`chat-consolidation-20260907/audit` directory.

## Historical consolidation checkpoint, 2026-09-10 UTC

This checkpoint supersedes the pending repair and validation claims below.
The latest verified protected attempt is
Expand Down
55 changes: 55 additions & 0 deletions docs/windows-quota-reproduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Windows quota directory reproduction

[Issue #219](https://github.com/OpenCoven/chat/issues/219) tracks the protected
Windows failure from run
[34611963297](https://github.com/OpenCoven/chat/actions/runs/34611963297):

```text
access-denied; root=harness-execution-aggregate; operation=directory-enumeration
```

The bounded diagnostic identifies the selected quota and filesystem operation.
It does not identify the denied descendant or establish a byte-quota breach.

## Native fixture

The existing Windows supervisor CI job invokes
`scripts/windows-owner-directory-quota.test.ps1` through the full supervisor
test suite. The fixture requires native Windows and the same account-provisioning
privileges as that suite. It can also run directly from the repository root:

```powershell
pwsh -NoLogo -NoProfile -NonInteractive -File scripts/windows-owner-directory-quota.test.ps1
```

The fixture creates a temporary isolated account and a directory containing a
known-size file. It checks readable-directory accounting, assigns the isolated
account as owner with Coven's protected owner-only directory DACL, and calls the
real terminal and background quota paths. The expected characterization is the
same bounded access-denial signature above. After restoring the fixture ACL, a
smaller quota must report an actual byte breach. A noninheritable directory handle
opened before ACL restriction retains restoration access and the original owner,
DACL and inheritance protection. Teardown restores fixture access
and removes the account and root, retaining any failures.

A matching result proves that this ACL shape can cause the observed monitor
failure. It does not prove that Coven, or any specific descendant, caused the
protected-run failure. A different result rejects this reproduction hypothesis
and must be investigated before selecting a repair.

## Separate cleanup result

The same protected job reported:

```text
root-delete:win32-3,root-survived:invalid-operation
```

This is a separate cleanup failure. The directory fixture does not reproduce it.
Investigate the native removal path, including path handling and missing or
replaced descendants, while preserving reparse safeguards and the requirement
that the owned root is actually removed.

The reproduction changes no production quota limits, private ACL rules, frozen
source bindings or validator scopes. A repair still requires native regression
proof, reviewed source and SDK binding updates, and fresh protected acceptance.
1 change: 1 addition & 0 deletions scripts/windows-job-supervisor.test.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ if (-not (Test-Path -LiteralPath $sourcePath -PathType Leaf)) {
Add-Type -TypeDefinition ([IO.File]::ReadAllText($sourcePath)) -Language CSharp
& (Join-Path $PSScriptRoot 'windows-process-sid-diagnostics.test.ps1')
& (Join-Path $PSScriptRoot 'windows-quota-diagnostics.test.ps1')
& (Join-Path $PSScriptRoot 'windows-owner-directory-quota.test.ps1')
& (Join-Path $PSScriptRoot 'windows-identity-cleanup-diagnostics.test.ps1')
& (Join-Path $PSScriptRoot 'windows-staging-binding.test.ps1')
& (Join-Path $PSScriptRoot 'windows-status-acl-probe.test.ps1')
Expand Down
222 changes: 222 additions & 0 deletions scripts/windows-owner-directory-quota.test.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
if (-not $IsWindows) { throw 'Owner-directory quota reproduction requires native Windows.' }
if (-not ('OpenCoven.WindowsJobSupervisor' -as [type])) {
Add-Type -TypeDefinition ([IO.File]::ReadAllText((Join-Path $PSScriptRoot 'windows-job-supervisor.cs'))) -Language CSharp
}

# Characterize the access boundary without changing production accounting.
# This is a controlled owner-only directory, not proof of the protected run's
# denied descendant. All filesystem reads below use the real quota methods.
$staticFlags = [Reflection.BindingFlags]'NonPublic,Static'
$instanceFlags = [Reflection.BindingFlags]'NonPublic,Instance'
$terminal = [OpenCoven.WindowsJobSupervisor].GetMethod('ApplyTerminalDirectoryQuotaCheck', $staticFlags)
$monitor = [OpenCoven.WindowsJobSupervisor].GetMethod('MonitorDirectoryQuotasAsync', $staticFlags)
$stateType = [OpenCoven.WindowsJobSupervisor].GetNestedType('DirectoryQuotaFailureState', [Reflection.BindingFlags]'NonPublic')
$enablePrivilege = [OpenCoven.WindowsJobSupervisor].GetMethod('EnablePrivilege', $staticFlags)
foreach ($method in @($terminal, $monitor, $stateType, $enablePrivilege)) {
if ($null -eq $method) { throw 'Native owner-directory fixture contract is missing.' }
}
if (-not ('OpenCoven.Tests.OwnerDirectoryQuotaFixture' -as [type])) {
Add-Type -Language CSharp -TypeDefinition @'
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
namespace OpenCoven.Tests
{
public sealed class OwnerDirectoryQuotaFixture : IDisposable
{
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetFileSecurityW(string path, uint information, byte[] descriptor);

// Retain access before revoking the supervisor's directory permissions.
// A null SECURITY_ATTRIBUTES pointer makes this handle noninheritable.
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr CreateFileW(string path, uint access, uint share,
IntPtr attributes, uint creation, uint flags, IntPtr template);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("kernel32.dll")]
private static extern IntPtr LocalFree(IntPtr memory);
[DllImport("advapi32.dll")]
private static extern uint GetSecurityInfo(IntPtr handle, uint type, uint information,
out IntPtr owner, out IntPtr group, out IntPtr dacl, out IntPtr sacl, out IntPtr descriptor);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetSecurityDescriptorControl(IntPtr descriptor, out ushort control, out uint revision);
[DllImport("advapi32.dll")]
private static extern uint SetSecurityInfo(IntPtr handle, uint type, uint information,
IntPtr owner, IntPtr group, IntPtr dacl, IntPtr sacl);

private IntPtr handle;
private IntPtr descriptor;
private IntPtr owner;
private IntPtr dacl;
private uint restoreInformation;
private bool restored;
private bool disposed;

public OwnerDirectoryQuotaFixture(string path)
{
// READ_CONTROL | WRITE_DAC | WRITE_OWNER; share read/write/delete;
// OPEN_EXISTING; BACKUP_SEMANTICS | OPEN_REPARSE_POINT.
handle = CreateFileW(path, 0x000E0000u, 7, IntPtr.Zero, 3, 0x02200000u, IntPtr.Zero);
if (handle == new IntPtr(-1))
{
handle = IntPtr.Zero;
throw new Win32Exception(Marshal.GetLastWin32Error(), "Fixture restoration handle could not be opened.");
}
try
{
IntPtr group, sacl;
uint error = GetSecurityInfo(handle, 1, 5, out owner, out group, out dacl, out sacl, out descriptor);
if (error != 0) throw new Win32Exception((int)error, "Fixture security could not be captured.");
ushort control;
uint revision;
if (!GetSecurityDescriptorControl(descriptor, out control, out revision))
throw new Win32Exception(Marshal.GetLastWin32Error(), "Fixture security control could not be read.");
// OWNER | DACL and the original DACL inheritance protection.
restoreInformation = 5u | ((control & 0x1000) != 0 ? 0x80000000u : 0x20000000u);
}
catch
{
Release();
throw;
}
}

public void Restore()
{
if (disposed) throw new ObjectDisposedException(nameof(OwnerDirectoryQuotaFixture));
if (restored) return;
uint error = SetSecurityInfo(handle, 1, restoreInformation, owner, IntPtr.Zero, dacl, IntPtr.Zero);
if (error != 0) throw new Win32Exception((int)error, "Fixture security restoration failed.");
restored = true;
}

private void Release()
{
if (descriptor != IntPtr.Zero) { LocalFree(descriptor); descriptor = IntPtr.Zero; }
if (handle != IntPtr.Zero) { CloseHandle(handle); handle = IntPtr.Zero; }
}

public void Dispose()
{
if (disposed) return;
try { Restore(); }
finally { disposed = true; Release(); }
}

public static void Protect(string path, string ownerSid)
{
// Match Coven's owner-only directory DACL, with the fixture owner
// explicitly bound to the real isolated account provisioned below.
var descriptor = new RawSecurityDescriptor("O:" + ownerSid + "D:P(A;OICI;GA;;;OW)");
var bytes = new byte[descriptor.BinaryLength];
descriptor.GetBinaryForm(bytes, 0);
if (!SetFileSecurityW(path, 0x80000005u, bytes))
throw new Win32Exception(Marshal.GetLastWin32Error(), "Fixture owner-only directory setup failed.");
}
}
}
'@
}

$fixtureRoot = Join-Path ([IO.Path]::GetTempPath()) ('opencoven-owner-directory-' + [Guid]::NewGuid().ToString('N'))
$identity = $null
$directory = $null
$securityLease = $null
$state = $null
$cancellation = $null
$monitorTask = $null
$failures = [Collections.Generic.List[Exception]]::new()
try {
$identity = [OpenCoven.WindowsIsolatedUser]::Create($fixtureRoot)
$supervisorSid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
if ($identity.Sid -ceq $supervisorSid) { throw 'Fixture identities must differ.' }
$directory = Join-Path $identity.TempPath 'phase1-conformance-run-fixture'
[IO.Directory]::CreateDirectory($directory) | Out-Null
$securityLease = [OpenCoven.Tests.OwnerDirectoryQuotaFixture]::new($directory)
[IO.File]::WriteAllBytes((Join-Path $directory 'payload.bin'), [byte[]]::new(1024))
$quota = [OpenCoven.WindowsDirectoryQuota[]]@(
[OpenCoven.WindowsDirectoryQuota]::new('harness execution aggregate', $directory, 2048)
)
$baseline = [OpenCoven.WindowsJobRunResult]::new()
$terminal.Invoke($null, [object[]]@($baseline, $quota))
if ($baseline.ResourceQuotaExceeded -or $baseline.ResourceQuotaMonitorError) {
throw 'Readable owner-directory control failed quota accounting.'
}

$enablePrivilege.Invoke($null, [object[]]@('SeRestorePrivilege'))
[OpenCoven.Tests.OwnerDirectoryQuotaFixture]::Protect($directory, $identity.Sid)
$denied = [OpenCoven.WindowsJobRunResult]::new()
$terminal.Invoke($null, [object[]]@($denied, $quota))
if (-not $denied.ResourceQuotaExceeded -or -not $denied.ResourceQuotaMonitorError -or
$denied.ExitCode -eq 0 -or $denied.ResourceQuotaMonitorCategory -cne 'access-denied' -or
$denied.ResourceQuotaMonitorRoot -cne 'harness-execution-aggregate' -or
$denied.ResourceQuotaMonitorOperation -cne 'directory-enumeration') {
throw 'Owner-only directory did not reproduce the protected terminal quota signature.'
}
$state = [Activator]::CreateInstance($stateType, $true)
$cancellation = [Threading.CancellationTokenSource]::new(5000)
$monitorTask = $monitor.Invoke($null, [object[]]@($quota, $state, $cancellation.Token))
if (-not $monitorTask.Wait(6000)) { throw 'Owner-directory monitor did not terminate.' }
foreach ($pair in @(
@('MonitorErrorCategory', 'access-denied'),
@('MonitorErrorRoot', 'harness-execution-aggregate'),
@('MonitorErrorOperation', 'directory-enumeration'))) {
if ($stateType.GetProperty($pair[0], $instanceFlags).GetValue($state) -cne $pair[1]) {
throw 'Owner-only directory did not reproduce the protected background quota signature.'
}
}
if ([Security.Principal.WindowsIdentity]::GetCurrent().User.Value -cne $supervisorSid) {
throw 'Quota fixture changed supervisor identity.'
}

# Restore only this test fixture. Production private ACLs remain untouched.
$securityLease.Restore()
$overflow = [OpenCoven.WindowsJobRunResult]::new()
$terminal.Invoke($null, [object[]]@($overflow, [OpenCoven.WindowsDirectoryQuota[]]@(
[OpenCoven.WindowsDirectoryQuota]::new('harness execution aggregate', $directory, 512)
)))
if (-not $overflow.ResourceQuotaExceeded -or $overflow.ResourceQuotaMonitorError -or
$overflow.ResourceQuotaLabel -cne 'harness execution aggregate' -or $overflow.ExitCode -eq 0) {
throw 'Readable control did not enforce the actual byte quota.'
}
Write-Host 'Native isolated-owner directory reproduces bounded terminal/background quota denial; readable and overflow controls passed.'
} catch {
$failures.Add($_.Exception)
} finally {
try { if ($null -ne $cancellation) { $cancellation.Cancel() } }
catch { $failures.Add($_.Exception) }
try {
if ($null -ne $monitorTask -and -not $monitorTask.Wait(6000)) {
throw [TimeoutException]::new('Owner-directory monitor survived cancellation.')
}
} catch { $failures.Add($_.Exception) }
# Do not dispose state underneath a worker that failed to stop. The fixture
# fails in that case, while still attempting ACL and account cleanup below.
if ($null -eq $monitorTask -or $monitorTask.IsCompleted) {
try { if ($null -ne $state) { $state.Dispose() } }
catch { $failures.Add($_.Exception) }
try { if ($null -ne $cancellation) { $cancellation.Dispose() } }
catch { $failures.Add($_.Exception) }
}
if ($null -ne $identity) {
try {
if ($null -ne $securityLease) { $securityLease.Dispose() }
} catch { $failures.Add($_.Exception) }
try { $identity.Dispose() }
catch { $failures.Add($_.Exception) }
}
}
if ([IO.Directory]::Exists($fixtureRoot)) {
$failures.Add([IO.IOException]::new('Owner-directory fixture survived cleanup.'))
}
if ($failures.Count -gt 0) {
throw [AggregateException]::new('Native owner-directory reproduction failed.', $failures.ToArray())
}
Write-Host 'Native owner-directory fixture cleanup passed.'
Loading
Loading