mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-09 18:28:15 +01:00
feat(skills): absorb pstack's blast radius, transcript recall, vet-the-number and design-twice as lazy sections
/investigate gains sections/blast-radius.md (the one safety fact, the five-rung evidence ladder, look where grep stops, confirmed and cleared risks apart) with a Phase 4 pointer, and the shared-premise red flag before the 3-strike rule. /context-restore is carved for the first time: on NO_CHECKPOINTS, sections/transcripts.md mines this workspace's own transcripts (host stores declared in hosts/*.ts and rendered by TRANSCRIPT_SOURCES / TRANSCRIPT_DISCOVERY), a fixed 7-day window, never another project's folder, subagents return only findings, redaction before anything leaves, git and gh verify every artifact, a status-tagged brief. /benchmark is carved for the first time: sections/vet-the-number.md asks the seven questions before Phase 5 reports a comparison. /plan-eng-review gains sections/design-twice.md (a second structurally distinct shape compared on interface depth, the eight design red flags), bound by the autoplan methodology snapshot alongside review-sections.md. Ideas from pstack (Lauren Tan, MIT), rewritten in gstack's words; NOTICE.md. Garry, 2026-10-26: "Do it, send". Guards: carve-guards entries and measured lines, eleven plan-eng-review pins re-measured, periodic carve-section-loading cases for the two new carves, free tests with a fixture transcript. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
576839cb8c
commit
6b530ccc0b
42 files changed
+1186
-47
No files matched your search
@@ -140,6 +140,17 @@ export interface HostConfig {
|
||||
learningsMode?: 'full' | 'basic';
|
||||
/** Anti-prompt-injection boundary instruction for cross-model invocations. */
|
||||
boundaryInstruction?: string;
|
||||
|
||||
// --- Session transcripts ---
|
||||
/**
|
||||
* Where this host keeps its own chat transcripts on disk, read by
|
||||
* /context-restore's no-checkpoint fallback (sections/transcripts.md).
|
||||
* `root` is the path pattern shown to the user; `layout` says how the
|
||||
* current workspace's files are told apart from another project's. Absent:
|
||||
* the host declares no transcript store, and the skill says so and falls
|
||||
* back to the shared record and git.
|
||||
*/
|
||||
transcripts?: { root: string; layout: string };
|
||||
}
|
||||
|
||||
// --- Validation ---
|
||||
|
||||
@@ -55,6 +55,7 @@ import { generateCoordinatorContract } from './coordinator-contract';
|
||||
import { generateAutoplanDriverCodes, generateAutoplanDriverCommands, generateAutoplanDriverFiles, generateAutoplanDriverGate, generateAutoplanDriverPhases, generateAutoplanDriverResultFormat } from './autoplan-driver';
|
||||
import { generateQAScope, generateQAExploratory, generateQAFunctional, generateQAResource, generateQAReview, generateQAReviewPreflight, generateQAMethodReads } from './qa';
|
||||
import { generateVoiceTriggerRouting } from './voice-triggers';
|
||||
import { generateTranscriptDiscovery, generateTranscriptSources } from './transcripts';
|
||||
|
||||
export const RESOLVERS: Record<string, ResolverFn> = {
|
||||
AUTOPLAN_PUBLICATION_HOOK: generateAutoplanPublicationHook,
|
||||
@@ -189,4 +190,6 @@ export const RESOLVERS: Record<string, ResolverFn> = {
|
||||
AUTOPLAN_DRIVER_CODES: generateAutoplanDriverCodes,
|
||||
SECTION,
|
||||
SECTION_INDEX,
|
||||
TRANSCRIPT_SOURCES: generateTranscriptSources,
|
||||
TRANSCRIPT_DISCOVERY: generateTranscriptDiscovery,
|
||||
};
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Transcript resolvers for /context-restore's no-checkpoint fallback
|
||||
* (context-restore/sections/transcripts.md.tmpl).
|
||||
*
|
||||
* {{TRANSCRIPT_SOURCES}} → the table of transcript stores, one row per host
|
||||
* that declares `transcripts` in hosts/<name>.ts,
|
||||
* plus the Capy row (none; the harness keeps no
|
||||
* transcript on the machine).
|
||||
* {{TRANSCRIPT_DISCOVERY}} → the bash block that lists THIS host's transcript
|
||||
* files for the current workspace only, inside the
|
||||
* window, and prints `TRANSCRIPTS: none (...)` on
|
||||
* Capy, on a host with no declared store, or when
|
||||
* the store is missing.
|
||||
*
|
||||
* The host table in hosts/*.ts is the single source of the paths; the prose
|
||||
* never hand-writes them. test/context-restore-transcripts.test.ts runs the
|
||||
* discovery block against fixture transcripts.
|
||||
*/
|
||||
import { ALL_HOST_CONFIGS, getHostConfig } from '../../hosts/index';
|
||||
import type { TemplateContext } from './types';
|
||||
|
||||
export const CAPY_NO_TRANSCRIPTS = 'TRANSCRIPTS: none (Capy keeps no session transcript on this machine; use the shared record and git)';
|
||||
|
||||
export function generateTranscriptSources(): string {
|
||||
const rows = ALL_HOST_CONFIGS
|
||||
.filter(h => h.transcripts)
|
||||
.map(h => `| ${h.displayName} | \`${h.transcripts!.root}\` | ${h.transcripts!.layout} |`);
|
||||
return [
|
||||
'| Host | Transcripts | How this workspace\'s files are told apart |',
|
||||
'|---|---|---|',
|
||||
...rows,
|
||||
'| Capy (any model) | none | the harness keeps no transcript on the machine; say so and use the shared record and git |',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
export function generateTranscriptDiscovery(ctx: TemplateContext): string {
|
||||
const host = getHostConfig(ctx.host);
|
||||
const slugBin = `${ctx.paths.binDir}/gstack-slug`;
|
||||
const head = [
|
||||
'TRANSCRIPT_DAYS="${TRANSCRIPT_DAYS:-7}"',
|
||||
`PROJECT_ROOT=$(${slugBin} --get PROJECT_ROOT 2>/dev/null) || PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)`,
|
||||
'echo "TRANSCRIPT_WINDOW: last $TRANSCRIPT_DAYS days"',
|
||||
'echo "TRANSCRIPT_PROJECT: $PROJECT_ROOT"',
|
||||
'if [ -n "${GSTACK_CAPY:-}" ]; then',
|
||||
` echo "${CAPY_NO_TRANSCRIPTS}"`,
|
||||
];
|
||||
let body: string[];
|
||||
if (ctx.host === 'claude') {
|
||||
body = [
|
||||
'else',
|
||||
' TRANSCRIPT_DIR="$HOME/.claude/projects/$(printf \'%s\' "$PROJECT_ROOT" | sed \'s/[^A-Za-z0-9]/-/g\')"',
|
||||
' if [ -d "$TRANSCRIPT_DIR" ]; then',
|
||||
' TRANSCRIPT_COUNT=0',
|
||||
' while IFS= read -r f; do TRANSCRIPT_COUNT=$((TRANSCRIPT_COUNT + 1)); echo "TRANSCRIPT: $f"; done < <(find "$TRANSCRIPT_DIR" -maxdepth 1 -name \'*.jsonl\' -mtime -"$TRANSCRIPT_DAYS" 2>/dev/null | sort)',
|
||||
' echo "TRANSCRIPTS: $TRANSCRIPT_DIR ($TRANSCRIPT_COUNT files in the last $TRANSCRIPT_DAYS days)"',
|
||||
' else',
|
||||
' echo "TRANSCRIPTS: none ($TRANSCRIPT_DIR is missing; this workspace has no Claude Code transcripts)"',
|
||||
' fi',
|
||||
'fi',
|
||||
];
|
||||
} else if (ctx.host === 'codex') {
|
||||
body = [
|
||||
'else',
|
||||
' TRANSCRIPT_DIR="$HOME/.codex/sessions"',
|
||||
' if [ -d "$TRANSCRIPT_DIR" ]; then',
|
||||
' TRANSCRIPT_COUNT=0',
|
||||
' while IFS= read -r f; do',
|
||||
' head -c 4096 "$f" 2>/dev/null | grep -qF -- "\\"cwd\\":\\"$PROJECT_ROOT\\"" || continue',
|
||||
' TRANSCRIPT_COUNT=$((TRANSCRIPT_COUNT + 1)); echo "TRANSCRIPT: $f"',
|
||||
' done < <(find "$TRANSCRIPT_DIR" -type f -name \'rollout-*.jsonl\' -mtime -"$TRANSCRIPT_DAYS" 2>/dev/null | sort)',
|
||||
' echo "TRANSCRIPTS: $TRANSCRIPT_DIR ($TRANSCRIPT_COUNT files whose cwd is this workspace, in the last $TRANSCRIPT_DAYS days)"',
|
||||
' else',
|
||||
' echo "TRANSCRIPTS: none ($TRANSCRIPT_DIR is missing; this machine has no Codex transcripts)"',
|
||||
' fi',
|
||||
'fi',
|
||||
];
|
||||
} else {
|
||||
body = [
|
||||
'else',
|
||||
` echo "TRANSCRIPTS: none (${host.displayName} declares no transcript store gstack may read; use the shared record and git)"`,
|
||||
'fi',
|
||||
];
|
||||
}
|
||||
return ['```bash', ...head, ...body, '```'].join('\n');
|
||||
}
|
||||
Reference in new issue
Block a user