@ericrisco/rsc 4.0.4 → 4.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/manifest.json +1 -1
- package/package.json +1 -1
- package/skills/asdd/SKILL.md +3 -1
- package/skills/implement/SKILL.md +1 -1
- package/targets/claude.js +23 -1
package/manifest.json
CHANGED
package/package.json
CHANGED
package/skills/asdd/SKILL.md
CHANGED
|
@@ -61,7 +61,7 @@ Every spec answers four questions, and `spec:gate` refuses one dated 2026-11-03
|
|
|
61
61
|
|
|
62
62
|
Tier 2, a contradiction with a recorded decision, a gap that would make the build unsafe, or no convergence in 3 rounds: the task goes to the **decision queue** (`## Decision queue` in `progress/<slug>.md`) with its evidence, and the agent **continues with the independent tasks**. The run never waits at 2 a.m. for an answer.
|
|
63
63
|
|
|
64
|
-
Every entry carries a kind, one line each:
|
|
64
|
+
Every entry carries a kind, one line each, in exactly this form (no bold, no other bullet):
|
|
65
65
|
|
|
66
66
|
```markdown
|
|
67
67
|
- [blocking] Q3 — <what must be decided>, <evidence>, <task>
|
|
@@ -102,6 +102,8 @@ Autopilot does not stop the run for questions — it **parks**: real ambiguity,
|
|
|
102
102
|
- `implement` parks `blocking` items and continues with the independent tasks.
|
|
103
103
|
- `ship` lands by the rule below.
|
|
104
104
|
|
|
105
|
+
**Never hand the turn back mid-run.** No "¿sigo?" / "shall I continue?": not between phases, not while reviewers run. Background reviewers are waited for (their completion notice, or run them in the foreground); ending the turn to wait ends a headless run. A later "continue" from the person resumes the run; it is **not** approval for a tier-2 merge, which needs an explicit yes to that merge.
|
|
106
|
+
|
|
105
107
|
**Landing — there is always a legal path.** A remote exists → open a PR; self-merge only when `rsc risk` says tier 0-1, CI is green and no `blocking` entry is open; `review-after` entries go into the PR body. No remote → **park**: leave the branch committed, write the explainer, the open entries and the exact merge command for the human into `progress/<slug>.md`, and stop. Never merge locally around the branch guard: when `rsc main status` says `closed: true`, the guard denies it.
|
|
106
108
|
|
|
107
109
|
Narrate in the `orient` voice: name each stage as it passes and show its artifact, one line each.
|
|
@@ -115,7 +115,7 @@ review of the task, this first one included. Round 1 is the task's first review,
|
|
|
115
115
|
| --- | --- |
|
|
116
116
|
| 0 | none — the controls (e) still run |
|
|
117
117
|
| 1 | one fresh-context reviewer; frozen brief in `references/per-task-review.md` |
|
|
118
|
-
| 2 | the three refuters (`refuter-correctness` · `refuter-security` · `refuter-tests`) in parallel, as `../review/SKILL.md` runs them; then `review ledger panel <slug>/<task> --lenses correctness,security,tests` — the push gate checks it |
|
|
118
|
+
| 2 | the three refuters (`refuter-correctness` · `refuter-security` · `refuter-tests`) in parallel, as `../review/SKILL.md` runs them; then `review ledger panel <slug>/<task> --lenses correctness,security,tests` — the push gate checks it. Wait for every reviewer inside the turn; never end the turn to ask whether to continue |
|
|
119
119
|
|
|
120
120
|
Every reviewer gets the **spec**, the **diff as a file** (`scripts/review-package <BASE> <HEAD>`, BASE
|
|
121
121
|
= the task's *recorded* base sha, never `HEAD~1`), the **surrounding code** at that sha (not just the
|
package/targets/claude.js
CHANGED
|
@@ -45,6 +45,8 @@ export function hookWiringOf(entry) {
|
|
|
45
45
|
// plus the legacy cat-form) from settings.json, across all events. User hooks and
|
|
46
46
|
// other settings are preserved. Empty event arrays (and an empty hooks object) are
|
|
47
47
|
// pruned so we don't leave noise behind.
|
|
48
|
+
const ATTRIBUTION_MARKER = '.rsc/attribution-default';
|
|
49
|
+
|
|
48
50
|
export function unwireHook(paths) {
|
|
49
51
|
// The bootstrap lives in the COMMITTED tree, so leaving it behind does not just orphan a file the
|
|
50
52
|
// way a stray `.rsc/` entry would — it leaves an executable in something the user pushes. Nothing
|
|
@@ -62,7 +64,18 @@ export function unwireHook(paths) {
|
|
|
62
64
|
if (!existsSync(file)) return removed;
|
|
63
65
|
let settings;
|
|
64
66
|
try { settings = JSON.parse(readFileSync(file, 'utf8')); } catch { return removed; }
|
|
65
|
-
|
|
67
|
+
// wireHook's attribution default goes back out with it — only when wireHook wrote it (the marker)
|
|
68
|
+
// and it is still untouched. The same value set by the person before rsc stays theirs.
|
|
69
|
+
const marker = join(paths.projectRoot, ATTRIBUTION_MARKER);
|
|
70
|
+
const a = settings.attribution;
|
|
71
|
+
const ours = existsSync(marker) && a && Object.keys(a).length === 2 && a.commit === '' && a.pr === '';
|
|
72
|
+
if (ours) delete settings.attribution;
|
|
73
|
+
try { rmSync(marker, { force: true }); } catch { /* cleanup never fails the uninstall */ }
|
|
74
|
+
if (!settings.hooks) {
|
|
75
|
+
if (!ours) return removed;
|
|
76
|
+
writeFileSync(file, JSON.stringify(settings, null, 2) + '\n');
|
|
77
|
+
return [...removed, file];
|
|
78
|
+
}
|
|
66
79
|
for (const event of Object.keys(settings.hooks)) {
|
|
67
80
|
settings.hooks[event] = (settings.hooks[event] || []).filter((e) => {
|
|
68
81
|
const s = hookWiringOf(e);
|
|
@@ -319,6 +332,15 @@ export function wireHook(paths, sourceMd, policy = {}) {
|
|
|
319
332
|
}
|
|
320
333
|
if (!settings.hooks.PreToolUse.length) delete settings.hooks.PreToolUse;
|
|
321
334
|
|
|
335
|
+
// Authorship is the responsible person, never an AI trailer (constitution P8). Claude Code's own
|
|
336
|
+
// default adds a Co-Authored-By line to commits and a footer to PRs, and the 4.0.4 run had to rebase
|
|
337
|
+
// them out by hand. Empty strings hide both. A choice already in the file is the person's and stays.
|
|
338
|
+
if (settings.attribution === undefined && settings.includeCoAuthoredBy === undefined) {
|
|
339
|
+
settings.attribution = { commit: '', pr: '' };
|
|
340
|
+
mkdirSync(join(paths.projectRoot, '.rsc'), { recursive: true });
|
|
341
|
+
writeFileSync(join(paths.projectRoot, ATTRIBUTION_MARKER), '');
|
|
342
|
+
}
|
|
343
|
+
|
|
322
344
|
mkdirSync(dirname(file), { recursive: true });
|
|
323
345
|
writeFileSync(file, JSON.stringify(settings, null, 2) + '\n');
|
|
324
346
|
|