mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-03 07:18:03 +01:00
v1.92.69.0 fix: lock developer-profile writers so overlapping derives keep every session (#3437, #3435) (#3738)
* fix(plan-tune): lock developer-profile writes and give derive a unique temp file (#3437) Concurrent background --derive runs shared developer-profile.json.tmp and rewrote the whole profile unlocked, so renames failed with ENOENT and a concurrent --log-session was dropped. Every read-modify-write now holds developer-profile.json.lock and writes a mktemp file. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * chore(plan-tune): remove applySignal and newDimensionTotals (#3435) Both lost their last production caller when --derive moved onto accumulateSignals; only three unit tests referenced them. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes Use the PID in the lock token, anchor a relative state root once so do_derive's cd cannot leak the lock, and note the stale-takeover tradeoff. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: pre-landing review fixes (pass 2) Keep Windows drive-letter state roots absolute when anchoring a relative root, and say which writers do not take the lock yet. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: take over a lock only from a dead holder, one taker at a time Step 11 voices: a late stale-lock mv could evict a fresh owner, a failed mv spun past the timeout, and the 10 s give-up sat under the 30 s stale age. Takeover now checks the holder's pid, re-reads the owner under a takeover lock, falls through to the give-up on failure, and reports an unwritable state directory at once. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix: take over an owned lock older than 5 minutes (pid reuse) A crashed holder whose pid now belongs to a live process kept its lock forever. An owned lock past 5 minutes now counts as abandoned, and cleanup removes a takeover lock this writer holds. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: changelog fragment for the profile lock (#3437) and dead-helper removal (#3435) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: say the 5-minute takeover applies whatever the pid Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test: keep the give-up test inside the type ratchet Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
1a22ae9652
commit
7762c39a4e
8 files changed
+288
-84
No files matched your search
@@ -306,29 +306,6 @@ export function resolveOptionKey(question_id: string, choice: string): string |
|
||||
return tie ? undefined : best;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a user choice for a question to the running dimension totals.
|
||||
*
|
||||
* @param dims - running total of dimension nudges (mutated)
|
||||
* @param signal_key - from the question registry entry
|
||||
* @param user_choice - the option key the user selected
|
||||
* @returns list of dimension deltas applied (empty if no mapping)
|
||||
*/
|
||||
export function applySignal(
|
||||
dims: Record<Dimension, number>,
|
||||
signal_key: string,
|
||||
user_choice: string,
|
||||
): DimensionDelta[] {
|
||||
const subMap = SIGNAL_MAP[signal_key];
|
||||
if (!subMap) return [];
|
||||
const deltas = subMap[user_choice];
|
||||
if (!deltas) return [];
|
||||
for (const { dim, delta } of deltas) {
|
||||
dims[dim] = (dims[dim] ?? 0) + delta;
|
||||
}
|
||||
return deltas;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that every signal_key referenced in the registry has a matching
|
||||
* entry in SIGNAL_MAP. Called by tests to catch drift.
|
||||
@@ -353,17 +330,6 @@ export function validateRegistrySignalKeys(): {
|
||||
return { missing, extra };
|
||||
}
|
||||
|
||||
/** Empty dimension totals — starting point for derivation. */
|
||||
export function newDimensionTotals(): Record<Dimension, number> {
|
||||
return {
|
||||
scope_appetite: 0,
|
||||
risk_tolerance: 0,
|
||||
detail_preference: 0,
|
||||
autonomy: 0,
|
||||
architecture_care: 0,
|
||||
};
|
||||
}
|
||||
|
||||
/** Sigmoid clamp: map accumulated delta total to [0, 1]. */
|
||||
export function normalizeToDimensionValue(total: number): number {
|
||||
// Simple sigmoid: each 1.0 of accumulated delta approaches saturation.
|
||||
|
||||
Reference in new issue
Block a user