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
32 changes: 16 additions & 16 deletions docs/project-statistics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1199,26 +1199,26 @@ Profil 2 verwendet Git-getrackte Textdateien und sichtbare Git-Aktivitaet. Die W

| Kennzahl / Metric | Wert / Value |
|---|---:|
| Textbasis / Text base | 611832 lines |
| Textbasis / Text base | 611885 lines |
| Textdateien / Text files | 3039 |
| Beobachtbarer Zeitraum / Observable period | 2025-08-24..2026-08-16 |
| Aktivtage / Active days | 90 |
| Relevante Commits / Relevant commits | 551 |
| Zeilen je Aktivtag / Lines per active day | 6798.1 |
| Beobachtbarer Zeitraum / Observable period | 2025-08-24..2026-08-17 |
| Aktivtage / Active days | 91 |
| Relevante Commits / Relevant commits | 552 |
| Zeilen je Aktivtag / Lines per active day | 6724.0 |
| Peak-Tag im Fenster / Peak day in window | 2026-03-22 / 321183 |
| Peak-Woche im Fenster / Peak week in window | 2026-03-22 / 373576 |
| Laengste Serie / Longest streak | 17 days |
| Speedup vs. 80 lines/day | 85.0x |
| Speedup vs. 125 lines/day | 54.4x |
| Methodik / Methodology | v2; source `841de095cf8d` |
| Speedup vs. 80 lines/day | 84.1x |
| Speedup vs. 125 lines/day | 53.8x |
| Methodik / Methodology | v2; source `063befae6cab` |

### Artefaktmix / Artifact Mix

```text
Produktiv / Production [####................] 22.4% | 137243
Tests [##..................] 8.0% | 48722
Dokumentation / Documentation [#########...........] 43.5% | 265869
Skripte / Scripts [#...................] 3.7% | 22435
Skripte / Scripts [#...................] 3.7% | 22488
Konfiguration / Configuration [#...................] 6.2% | 37729
Daten und Medien / Data and media [#...................] 0.0% | 1
Sonstiger Text / Other text [###.................] 16.3% | 99833
Expand All @@ -1244,7 +1244,7 @@ Sa/Sa 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
```text
Wochen / Weeks 27..52 | 2026-02-22..2026-08-22
So/Su 0 4 4 0 4 4 0 4 0 0 4 4 0 0 4 0 4 0 0 0 4 4 4 1 4 4
Mo/Mo 0 0 0 4 4 4 0 1 4 0 4 0 0 0 1 0 2 0 3 1 4 4 0 0 0 -
Mo/Mo 0 0 0 4 4 4 0 1 4 0 4 0 0 0 1 0 2 0 3 1 4 4 0 0 0 2
Di/Tu 0 0 0 3 3 4 0 0 0 0 3 4 0 3 2 0 0 0 2 0 4 4 4 0 0 -
Mi/We 0 0 0 1 4 0 0 0 3 0 4 1 0 0 2 0 4 0 2 0 4 2 4 0 0 -
Do/Th 0 0 0 0 0 0 0 0 0 4 0 0 3 3 3 4 2 0 0 0 4 4 0 0 4 -
Expand Down Expand Up @@ -1409,8 +1409,8 @@ Die festen Slots halten den Phasenvergleich auch bei fehlenden oder spaeter erga

```text
Scale: 0..100x
80 lines/day [#################...] 85.0x
125 lines/day [###########.........] 54.4x
80 lines/day [#################...] 84.1x
125 lines/day [###########.........] 53.8x
```

Die Faktoren vergleichen sichtbare Lieferdichte mit den dokumentierten manuellen Referenzen. Sie messen keine Arbeitszeit.
Expand All @@ -1423,7 +1423,7 @@ Die Faktoren vergleichen sichtbare Lieferdichte mit den dokumentierten manuellen
Scale: 0..10000 lines/day
Experienced manual [#...................] 80
Thorsten solo [#...................] 125
Visible repository [##############......] 6798.1
Visible repository [#############.......] 6724.0
```

Die gemeinsame Skala vergleicht Referenzen und sichtbare Lieferdichte. Sie schreibt die Git-Aktivitaet keiner Person oder KI pauschal zu.
Expand All @@ -1432,9 +1432,9 @@ Die gemeinsame Skala vergleicht Referenzen und sichtbare Lieferdichte. Sie schre

### Textalternative / Text Alternative

DE: Das Fenster beginnt am 2025-08-24 und endet am 2026-08-16. Es enthaelt 90 aktive und 268 inaktive vergangene Tage. Peak-Tag: 2026-03-22 / 321183. Peak-Woche: 2026-03-22 / 373576. Laengste Serie: 17 Tage (2026-07-10..2026-07-26).
DE: Das Fenster beginnt am 2025-08-24 und endet am 2026-08-17. Es enthaelt 91 aktive und 268 inaktive vergangene Tage. Peak-Tag: 2026-03-22 / 321183. Peak-Woche: 2026-03-22 / 373576. Laengste Serie: 17 Tage (2026-07-10..2026-07-26).

*EN: The window starts on 2025-08-24 and ends on 2026-08-16. It contains 90 active and 268 inactive elapsed days. Peak day: 2026-03-22 / 321183. Peak week: 2026-03-22 / 373576. Longest streak: 17 days (2026-07-10..2026-07-26).*
*EN: The window starts on 2025-08-24 and ends on 2026-08-17. It contains 91 active and 268 inactive elapsed days. Peak day: 2026-03-22 / 321183. Peak week: 2026-03-22 / 373576. Longest streak: 17 days (2026-07-10..2026-07-26).*

| Monat / Month | Geaenderte Textzeilen / Changed text lines |
|---|---:|
Expand All @@ -1449,6 +1449,6 @@ DE: Das Fenster beginnt am 2025-08-24 und endet am 2026-08-16. Es enthaelt 90 ak
| 2026-05 | 273853 |
| 2026-06 | 42176 |
| 2026-07 | 205615 |
| 2026-08 | 23729 |
| 2026-08 | 23828 |

<!-- project-statistics-v2:end -->
6 changes: 3 additions & 3 deletions scripts/lib/agentic_workspace_fleet.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def is_transient_git_failure(detail: str) -> bool:
return False
return bool(
re.search(
r"timed?\s*out|timeout|connection\s+(?:reset|closed|aborted)|temporary failure|"
r"timed?\s*out|timeout|connection\s+(?:was\s+)?(?:reset|closed|aborted)|temporary failure|"
r"could not resolve host|name resolution|http\s+50[234]",
detail,
re.IGNORECASE,
Expand Down Expand Up @@ -532,13 +532,13 @@ def classify_repository(
upstream=upstream_name, retryAttempts=pull_attempts,
resumeAccepted=resume_accepted, freshnessAttempt=freshness,
defaultBranchEvidence=default_evidence, pullAttempt=pull_evidence,
mutationAllowed=not dirty
mutationAllowed=not dirty or resume_accepted
)
return target_result(
target, branch=branch_name, upstream=upstream_name,
retryAttempts=fetch_attempts, resumeAccepted=resume_accepted,
freshnessAttempt=freshness, defaultBranchEvidence=default_evidence,
mutationAllowed=not dirty
mutationAllowed=not dirty or resume_accepted
)


Expand Down
2 changes: 1 addition & 1 deletion scripts/lib/windows-maintenance-hardening.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ function Test-HBTransientFailure {
if ($Summary -match '(?i)auth(?:entication|orization)?|permission|forbidden|not found|dirty|ahead|diverged') {
return $false
}
return $Summary -match '(?i)timed?\s*out|timeout|connection\s+(?:reset|closed|aborted)|temporary failure|could not resolve host|name resolution|http\s+50[234]'
return $Summary -match '(?i)timed?\s*out|timeout|connection\s+(?:was\s+)?(?:reset|closed|aborted)|temporary failure|could not resolve host|name resolution|http\s+50[234]'
}

function Invoke-HBWithRetry {
Expand Down
71 changes: 62 additions & 9 deletions scripts/maintain-agentic-workspace.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,7 @@ $script:RepairApplied = $false
$script:PreviewDrift = $false
$script:NonBlockingWarnings = 0
$script:ResumeAllowedPaths = @()
$script:ResumeEvidenceFiles = @()
$exitCode = 0
$transcriptStarted = $false
$runId = if ($requestedRunId) {
Expand Down Expand Up @@ -694,6 +695,8 @@ function Invoke-HBPythonCommand {
param([Parameter(Mandatory)][string[]]$Arguments)
$commandArguments = @($script:HBPythonLauncher.PrefixArguments) + @($Arguments)
& $script:HBPythonLauncher.FilePath @commandArguments
$pythonExitCode = $LASTEXITCODE
Set-Variable -Name LASTEXITCODE -Value $pythonExitCode -Scope 1
}

function ConvertTo-HBEventStatus {
Expand Down Expand Up @@ -1060,6 +1063,13 @@ function Initialize-HBResumeState {
throw "Resume-Evidence passt nicht exakt / does not match exactly: $($validation.Reason)"
}
$script:ResumeAllowedPaths = @($evidence.files | ForEach-Object { [string]$_.path })
$script:ResumeEvidenceFiles = @($evidence.files | ForEach-Object {
[pscustomobject]@{
Path = [string]$_.path
BeforeSha256 = [string]$_.beforeSha256
AfterSha256 = [string]$_.afterSha256
}
})
$script:RepairApplied = $true
Write-Host "OK: Resume-Evidence exakt validiert / exact resume evidence validated: $($validation.RunId)"
return
Expand All @@ -1070,10 +1080,20 @@ function Initialize-HBResumeState {
}

function Get-HBPropagationPlan {
$manifestPath = Join-Path $sourceRoot 'scripts/config/agentic-toolchain-maintenance-files.json'
$manifest = Get-Content -LiteralPath $manifestPath -Raw -Encoding UTF8 | ConvertFrom-Json
$propagationManifestPath = Join-Path $sourceRoot 'scripts/config/agentic-toolchain-maintenance-files.json'
$manifest = Get-Content -LiteralPath $propagationManifestPath -Raw -Encoding UTF8 | ConvertFrom-Json
$propagationExceptions = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
$exceptionsProperty = $manifest.PSObject.Properties['exceptions']
if ($null -ne $exceptionsProperty) {
foreach ($exception in @($exceptionsProperty.Value)) {
[void]$propagationExceptions.Add(
"$([string]$exception.repositoryPath)`n$([string]$exception.path)"
)
}
}
$changes = [Collections.Generic.List[object]]::new()
foreach ($repository in Get-HBManagedRepositories) {
$repositoryRelative = [IO.Path]::GetRelativePath($HomeDir, $repository.Path).Replace('\', '/')
foreach ($file in @($manifest.files)) {
$source = Join-Path $sourceRoot ([string]$file.path)
$target = Join-Path $repository.Path ([string]$file.path)
Expand All @@ -1086,6 +1106,11 @@ function Get-HBPropagationPlan {
$different = $sourceHash -ne $targetHash
}
if (-not $different) { continue }
if ($propagationExceptions.Contains("${repositoryRelative}`n$([string]$file.path)") -and
(Test-Path -LiteralPath $target -PathType Leaf)) {
$null = & git -C $repository.Path ls-files --error-unmatch -- ([string]$file.path) 2>$null
if ($LASTEXITCODE -eq 0) { continue }
}
$changes.Add([pscustomobject]@{
Path = [IO.Path]::GetRelativePath($HomeDir, $target).Replace('\', '/')
BeforeSha256 = Get-HBFileSha256 -Path $target
Expand Down Expand Up @@ -1178,8 +1203,14 @@ function Invoke-HBPropagation {
if ($plannedChanges.Count -eq 0) {
throw 'Propagation meldet Drift ohne aktionsfaehige Dateien / reported drift without actionable files.'
}
$plannedPaths = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
foreach ($change in $plannedChanges) { [void]$plannedPaths.Add([string]$change.Path) }
$evidenceChanges = @(
$script:ResumeEvidenceFiles | Where-Object { -not $plannedPaths.Contains([string]$_.Path) }
$plannedChanges
)
$null = Write-HBResumeEvidence -Path $resumeEvidenceFile -RunId $runId `
-Phase 'propagation' -Files $plannedChanges -Status Prepared `
-Phase 'propagation' -Files $evidenceChanges -Status Prepared `
-NextAction 'Propagation ausfuehren und Hashes verifizieren / execute propagation and verify hashes'
& $propagation -HomeDir $HomeDir -Registry $registry
if ($LASTEXITCODE -ne 0) { throw 'Propagation fehlgeschlagen / failed.' }
Expand All @@ -1190,7 +1221,7 @@ function Invoke-HBPropagation {
}
}
$null = Write-HBResumeEvidence -Path $resumeEvidenceFile -RunId $runId `
-Phase 'propagation' -Files $plannedChanges -Status Applied `
-Phase 'propagation' -Files $evidenceChanges -Status Applied `
-NextAction 'Geaenderte Ziel-Repositories separat pruefen und liefern / review and deliver changed target repositories separately'
if ((Invoke-HBPropagationCheck) -ne 0) { throw 'Propagation-Abschlusspruefung fehlgeschlagen / final check failed.' }
$script:RepairApplied = $true
Expand Down Expand Up @@ -1336,6 +1367,21 @@ function Remove-HBPresetValidationTarget {
}
}

function Invoke-HBPresetInstallerProcess {
param(
[Parameter(Mandatory)][string] $Installer,
[Parameter(Mandatory)][object[]] $Arguments
)

# The installer deliberately throws when CheckOnly detects drift. A child
# process converts that terminating error into the exit-code contract the
# orchestrator needs before deciding whether repair is permitted.
$output = @(& pwsh -NoProfile -NonInteractive -File $Installer @Arguments 2>&1)
$status = if ($null -eq $LASTEXITCODE) { 0 } else { [int]$LASTEXITCODE }
$output | ForEach-Object { Write-Host "$_" }
return $status
}

function Invoke-HBPresetProfiles {
$installer = Join-Path $sourceRoot 'scripts/install-spec-kit-governance-presets.ps1'
if (-not (Test-Path -LiteralPath $installer -PathType Leaf)) {
Expand All @@ -1350,11 +1396,16 @@ function Invoke-HBPresetProfiles {
try {
$validationTarget = New-HBPresetValidationTarget -Repository $target.Path
if ($WhatIfPreference) {
& $installer -Repo @($validationTarget.Path) -PresetConfig $config -WhatIf
$previewStatus = Invoke-HBPresetInstallerProcess -Installer $installer -Arguments @(
'-Repo', $validationTarget.Path, '-PresetConfig', $config, '-WhatIf'
)
if ($previewStatus -ne 0) { throw "Preset-Vorschau fehlgeschlagen / preview failed: $($target.Path)" }
continue
}
& $installer -Repo @($validationTarget.Path) -PresetConfig $config -CheckOnly
if ($LASTEXITCODE -eq 0) { continue }
$checkStatus = Invoke-HBPresetInstallerProcess -Installer $installer -Arguments @(
'-Repo', $validationTarget.Path, '-PresetConfig', $config, '-CheckOnly'
)
if ($checkStatus -eq 0) { continue }
if ($validationTarget.Isolated) {
Write-HBWarning "Preset-Profil-Drift auf dem kanonischen Default-Branch erfordert einen eigenen Branch/PR / requires a dedicated branch/PR: $($target.Path)"
$script:Findings++
Expand All @@ -1365,8 +1416,10 @@ function Invoke-HBPresetProfiles {
$script:Findings++
continue
}
& $installer -Repo @($target.Path) -PresetConfig $config -Force
if ($LASTEXITCODE -ne 0) { throw "Preset-Reparatur fehlgeschlagen / repair failed: $($target.Path)" }
$repairStatus = Invoke-HBPresetInstallerProcess -Installer $installer -Arguments @(
'-Repo', $target.Path, '-PresetConfig', $config, '-Force'
)
if ($repairStatus -ne 0) { throw "Preset-Reparatur fehlgeschlagen / repair failed: $($target.Path)" }
$script:RepairApplied = $true
} catch {
Write-HBWarning $_.Exception.Message
Expand Down
Loading
Loading