@codyswann/lisa 4.27.4 → 4.27.6
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/all/copy-overwrite/scripts/lisa-enforcement-fallback.sh +27 -4
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +167 -2
- package/dist/cli/doctor-enforcement-coverage.d.ts +14 -0
- package/dist/cli/doctor-enforcement-coverage.d.ts.map +1 -0
- package/dist/cli/doctor-enforcement-coverage.js +103 -0
- package/dist/cli/doctor-enforcement-coverage.js.map +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +9 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/core/enforcement-census-report.d.ts +19 -0
- package/dist/core/enforcement-census-report.d.ts.map +1 -0
- package/dist/core/enforcement-census-report.js +198 -0
- package/dist/core/enforcement-census-report.js.map +1 -0
- package/dist/core/enforcement-census.d.ts +177 -0
- package/dist/core/enforcement-census.d.ts.map +1 -0
- package/dist/core/enforcement-census.js +252 -0
- package/dist/core/enforcement-census.js.map +1 -0
- package/dist/core/enforcement-coverage.d.ts +168 -0
- package/dist/core/enforcement-coverage.d.ts.map +1 -0
- package/dist/core/enforcement-coverage.js +342 -0
- package/dist/core/enforcement-coverage.js.map +1 -0
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +10 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +25 -7
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/migrations/ensure-push-default-safe.d.ts +50 -0
- package/dist/migrations/ensure-push-default-safe.d.ts.map +1 -0
- package/dist/migrations/ensure-push-default-safe.js +159 -0
- package/dist/migrations/ensure-push-default-safe.js.map +1 -0
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +3 -0
- package/dist/migrations/index.js.map +1 -1
- package/package.json +4 -3
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-setup-automations/SKILL.md +23 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa/skills/lisa-setup-automations/SKILL.md +23 -0
- package/plugins/lisa/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-setup-automations/SKILL.md +23 -0
- package/plugins/lisa-agy/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/skills/lisa-setup-automations/SKILL.md +23 -0
- package/plugins/lisa-copilot/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-setup-automations/SKILL.md +23 -0
- package/plugins/lisa-cursor/skills/lisa-sync-down/SKILL.md +8 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/lisa-setup-automations/SKILL.md +23 -0
- package/plugins/src/base/skills/lisa-sync-down/SKILL.md +8 -1
- package/scripts/lisa-commit-and-pr-local.sh +22 -6
- package/scripts/lisa-enforcement-census.mjs +168 -0
- package/scripts/lisa-enforcement-fallback.sh +27 -4
- package/typescript/copy-contents/.husky/pre-push +70 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Fleet enforcement census — re-measures how many host checkouts resolve a
|
|
4
|
+
* Lisa enforcement guard, and reports it.
|
|
5
|
+
*
|
|
6
|
+
* The per-session staleness notice in `scripts/lisa-enforcement-fallback.sh`
|
|
7
|
+
* tells THIS session about THIS checkout, which is right and is not the gap.
|
|
8
|
+
* The gap is that nobody was looking at the fleet, so the only fleet-wide
|
|
9
|
+
* number that ever existed was taken by hand and frozen in a comment
|
|
10
|
+
* (CodySwannGT/lisa#3490). This runs the measurement again, every time.
|
|
11
|
+
*
|
|
12
|
+
* Two properties it must keep:
|
|
13
|
+
*
|
|
14
|
+
* - It REPORTS. Its exit status is 0 for every finding about the fleet,
|
|
15
|
+
* including a fleet where every checkout is stale. A census that could
|
|
16
|
+
* redden someone's build would be routed around.
|
|
17
|
+
* - It keeps "resolves nothing" apart from "resolves something old". They are
|
|
18
|
+
* different failures with different remedies, and folding them loses the
|
|
19
|
+
* serious half.
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* node scripts/lisa-enforcement-census.mjs [options]
|
|
23
|
+
*
|
|
24
|
+
* Options:
|
|
25
|
+
* --roster <path> Roster file (default: .lisa.workspaces.json beside this repo)
|
|
26
|
+
* --scan <dir> Also discover checkouts under <dir>. Repeatable.
|
|
27
|
+
* --depth <n> How deep --scan descends (default 2)
|
|
28
|
+
* --reference <ver> Compare against this version instead of the newest found
|
|
29
|
+
* --redact Replace real paths with stable anonymous labels
|
|
30
|
+
* --json Emit the measured fleet as JSON
|
|
31
|
+
*
|
|
32
|
+
* Exit status: 0 for every fleet finding. 1 only when an explicitly named
|
|
33
|
+
* roster cannot be read, and 2 for a usage error — both are failures of the
|
|
34
|
+
* census's own inputs, never findings about the fleet.
|
|
35
|
+
*/
|
|
36
|
+
import path from "node:path";
|
|
37
|
+
import { fileURLToPath } from "node:url";
|
|
38
|
+
|
|
39
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
40
|
+
const repoRoot = path.resolve(here, "..");
|
|
41
|
+
|
|
42
|
+
const census = await import(
|
|
43
|
+
path.join(repoRoot, "dist", "core", "enforcement-census.js")
|
|
44
|
+
).catch(error => {
|
|
45
|
+
process.stderr.write(
|
|
46
|
+
`Could not load the census from dist/. Run \`bun run build:dist\` first.\n${error.message}\n`
|
|
47
|
+
);
|
|
48
|
+
process.exit(2);
|
|
49
|
+
});
|
|
50
|
+
const report = await import(
|
|
51
|
+
path.join(repoRoot, "dist", "core", "enforcement-census-report.js")
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const options = {
|
|
55
|
+
roster: null,
|
|
56
|
+
scans: [],
|
|
57
|
+
depth: 2,
|
|
58
|
+
reference: null,
|
|
59
|
+
redact: false,
|
|
60
|
+
json: false,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const argv = process.argv.slice(2);
|
|
64
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
65
|
+
const flag = argv[index];
|
|
66
|
+
const value = argv[index + 1];
|
|
67
|
+
// A value-taking flag left at the end of the line has no value. Assigning
|
|
68
|
+
// `undefined` there silently falls back to the default roster or drops the
|
|
69
|
+
// requested setting, so the run measures something other than what was
|
|
70
|
+
// asked for and says nothing about it — a census reporting the wrong fleet
|
|
71
|
+
// is worse than one that refuses. This is the census's own input being
|
|
72
|
+
// wrong, so it exits 2 like any other usage error and never as a finding.
|
|
73
|
+
const VALUE_FLAGS = ["--roster", "--scan", "--depth", "--reference"];
|
|
74
|
+
if (VALUE_FLAGS.includes(flag) && value === undefined) {
|
|
75
|
+
process.stderr.write(`${flag} requires a value\n`);
|
|
76
|
+
process.exit(2);
|
|
77
|
+
}
|
|
78
|
+
if (flag === "--roster") {
|
|
79
|
+
options.roster = value;
|
|
80
|
+
index += 1;
|
|
81
|
+
} else if (flag === "--scan") {
|
|
82
|
+
options.scans.push(value);
|
|
83
|
+
index += 1;
|
|
84
|
+
} else if (flag === "--depth") {
|
|
85
|
+
options.depth = Number.parseInt(value ?? "", 10);
|
|
86
|
+
index += 1;
|
|
87
|
+
} else if (flag === "--reference") {
|
|
88
|
+
options.reference = value;
|
|
89
|
+
index += 1;
|
|
90
|
+
} else if (flag === "--redact") {
|
|
91
|
+
options.redact = true;
|
|
92
|
+
} else if (flag === "--json") {
|
|
93
|
+
options.json = true;
|
|
94
|
+
} else if (flag === "--help" || flag === "-h") {
|
|
95
|
+
process.stdout.write(
|
|
96
|
+
"Usage: node scripts/lisa-enforcement-census.mjs [--roster <path>] [--scan <dir>] [--depth <n>] [--reference <ver>] [--redact] [--json]\n"
|
|
97
|
+
);
|
|
98
|
+
process.exit(0);
|
|
99
|
+
} else {
|
|
100
|
+
process.stderr.write(`Unknown option: ${flag}\n`);
|
|
101
|
+
process.exit(2);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (!Number.isInteger(options.depth) || options.depth < 0) {
|
|
106
|
+
process.stderr.write("--depth must be a non-negative integer\n");
|
|
107
|
+
process.exit(2);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const rosterPath =
|
|
111
|
+
options.roster ?? path.join(repoRoot, census.DEFAULT_ROSTER_FILE);
|
|
112
|
+
const rosterEntries = await census.readFleetRoster(rosterPath);
|
|
113
|
+
|
|
114
|
+
// An explicitly named roster that cannot be read is an input error, not a
|
|
115
|
+
// finding: the operator asked for a specific file and did not get it. A missing
|
|
116
|
+
// DEFAULT roster is neither — this repository is simply not a fleet hub — so it
|
|
117
|
+
// reports an empty fleet and still exits 0.
|
|
118
|
+
if (rosterEntries === null && options.roster !== null) {
|
|
119
|
+
process.stderr.write(`Could not read the roster: ${rosterPath}\n`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const scanned = (
|
|
124
|
+
await Promise.all(
|
|
125
|
+
options.scans.map(directory =>
|
|
126
|
+
census.scanForCheckouts(directory, options.depth)
|
|
127
|
+
)
|
|
128
|
+
)
|
|
129
|
+
).flat();
|
|
130
|
+
|
|
131
|
+
const roster = await census.dedupeRoster([
|
|
132
|
+
...(rosterEntries ?? []),
|
|
133
|
+
...scanned,
|
|
134
|
+
]);
|
|
135
|
+
|
|
136
|
+
const origins = [
|
|
137
|
+
rosterEntries === null ? null : rosterPath,
|
|
138
|
+
...options.scans.map(directory => `scan of ${directory}`),
|
|
139
|
+
].filter(Boolean);
|
|
140
|
+
|
|
141
|
+
const seedVersion = await import(path.join(repoRoot, "package.json"), {
|
|
142
|
+
with: { type: "json" },
|
|
143
|
+
})
|
|
144
|
+
.then(module => module.default.version ?? null)
|
|
145
|
+
.catch(() => null);
|
|
146
|
+
|
|
147
|
+
const measured = await census.runFleetCensus({
|
|
148
|
+
roster,
|
|
149
|
+
rosterOrigin: origins.length === 0 ? "no roster found" : origins.join(" + "),
|
|
150
|
+
seedVersion,
|
|
151
|
+
reference: options.reference,
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const output = options.redact ? report.redactCensus(measured) : measured;
|
|
155
|
+
|
|
156
|
+
process.stdout.write(
|
|
157
|
+
options.json
|
|
158
|
+
? `${JSON.stringify(output, null, 2)}\n`
|
|
159
|
+
: report.renderFleetCensusReport(output)
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
// Unconditional. Nothing above may change it.
|
|
163
|
+
//
|
|
164
|
+
// Set rather than called: `process.exit()` tears the process down synchronously
|
|
165
|
+
// and can drop a pending `process.stdout.write` when stdout is a pipe, which is
|
|
166
|
+
// exactly how this is read — piped to a pager, a file, or a scheduled loop's
|
|
167
|
+
// log. A truncated census reports a smaller fleet than it measured, silently.
|
|
168
|
+
process.exitCode = 0;
|
|
@@ -404,10 +404,33 @@ fi
|
|
|
404
404
|
# - `main` cut 80 releases in 24 hours, median gap 10 minutes. "Behind the
|
|
405
405
|
# newest Lisa on this disk" is the DEFAULT state of a checkout within
|
|
406
406
|
# minutes of being cut, through nothing anyone did wrong.
|
|
407
|
-
# -
|
|
408
|
-
#
|
|
409
|
-
#
|
|
410
|
-
#
|
|
407
|
+
# - Measured once across the host checkouts on one fleet: of those that
|
|
408
|
+
# resolved guards at all, every one was behind or undateable and none was
|
|
409
|
+
# current, several by a whole MAJOR — while a larger number resolved NO
|
|
410
|
+
# guard at all.
|
|
411
|
+
#
|
|
412
|
+
# That second reading used to be written here as a set of counts, and that was
|
|
413
|
+
# the wrong place for it. A number in a comment is a measurement, not a monitor:
|
|
414
|
+
# it was true on the day it was taken and nothing re-took it, so the drift after
|
|
415
|
+
# that date was unobserved — which is the same defect the number documents. The
|
|
416
|
+
# counts are therefore not restated here. Re-derive them:
|
|
417
|
+
#
|
|
418
|
+
# Run these FROM A LISA MONOREPO CHECKOUT — the census and the fleet roster are
|
|
419
|
+
# Lisa-monorepo artifacts, and this comment travels into host projects where
|
|
420
|
+
# neither exists. The script wrapper builds `dist/` first, which a fresh clone
|
|
421
|
+
# does not have:
|
|
422
|
+
#
|
|
423
|
+
# bun run lisa:enforcement-census # roster on this machine
|
|
424
|
+
# bun run lisa:enforcement-census -- --redact # safe to quote publicly
|
|
425
|
+
#
|
|
426
|
+
# In a host project the local half of the same question is `lisa doctor`, which
|
|
427
|
+
# reports what THIS checkout resolves and needs no roster.
|
|
428
|
+
#
|
|
429
|
+
# The census reports and never gates, and it keeps "resolves NO guard" apart
|
|
430
|
+
# from "resolves something old" — different failures, different remedies, and
|
|
431
|
+
# folding them is what made the unenforced checkouts easy to miss
|
|
432
|
+
# (CodySwannGT/lisa#3490). `lisa doctor` carries the same finding for the single
|
|
433
|
+
# checkout it is run in.
|
|
411
434
|
#
|
|
412
435
|
# So no distance threshold rescues it — even the strictest version predicate is
|
|
413
436
|
# permanently true across the fleet. The noise is the REPETITION, not the
|
|
@@ -87,6 +87,76 @@ if ! command -v node >/dev/null 2>&1; then
|
|
|
87
87
|
echo "❌ Push blocked: Node.js is required to validate tracker work items."
|
|
88
88
|
exit 1
|
|
89
89
|
fi
|
|
90
|
+
|
|
91
|
+
# BEGIN: push destination guard
|
|
92
|
+
# ---------------------------------------------------------------------------
|
|
93
|
+
# Refuse a push whose RESOLVED destination is a deploy branch it was not aimed
|
|
94
|
+
# at.
|
|
95
|
+
#
|
|
96
|
+
# `push.default=upstream` (and its deprecated spelling `tracking`) resolves a
|
|
97
|
+
# push's destination from the branch's UPSTREAM rather than from the branch
|
|
98
|
+
# named on the command line. A working branch created the ordinary way —
|
|
99
|
+
# `git checkout -b <branch> origin/main` — has `main` as its upstream, so the
|
|
100
|
+
# ordinary `git push -u origin <branch>` resolves to `refs/heads/main` and lands
|
|
101
|
+
# there. The push reports success. Branch protection and every required check
|
|
102
|
+
# are bypassed, and the operator is told only afterwards, if at all
|
|
103
|
+
# (CodySwannGT/lisa#3495).
|
|
104
|
+
#
|
|
105
|
+
# Measured in Lisa's own repository: two commits reached the default branch this
|
|
106
|
+
# way. Every detection control afterwards fired correctly — the bypass was
|
|
107
|
+
# reported, an agent force-push was refused, the release run was caught and
|
|
108
|
+
# cancelled — and the commits shipped in a published release regardless, because
|
|
109
|
+
# an ordinary unrelated merge cut a release before anyone could rewind. Nothing
|
|
110
|
+
# had prevented the original push. That is why this is a refusal and not a
|
|
111
|
+
# warning.
|
|
112
|
+
#
|
|
113
|
+
# WHY HERE, and not folded into a check that already exists.
|
|
114
|
+
#
|
|
115
|
+
# It reads the RESOLVED DESTINATION, in the third field of the stdin lines. That
|
|
116
|
+
# is the only place in the system where the destination git actually chose is
|
|
117
|
+
# observable; `push.default`, the branch's upstream and the command line are all
|
|
118
|
+
# proxies for it, and the accident is precisely a disagreement between the
|
|
119
|
+
# proxies and the answer. So the check has to live at the push moment, on this
|
|
120
|
+
# stream.
|
|
121
|
+
#
|
|
122
|
+
# It is UNCONDITIONAL. The traceability step below stands down when a project
|
|
123
|
+
# declares `gates.traceability`, and a guard a declaration can switch off is not
|
|
124
|
+
# a guard against an accident. It also runs BELOW the deletion-only guard, which
|
|
125
|
+
# exits first, so deleting a branch still needs no node.
|
|
126
|
+
#
|
|
127
|
+
# WHAT IT ALLOWS, deliberately: `main -> main`, so a merge landed locally still
|
|
128
|
+
# pushes; a `HEAD` local ref, which is how git spells a destination the pusher
|
|
129
|
+
# wrote out in full and how release automation pushes from a detached checkout;
|
|
130
|
+
# and every push whose destination is not a deploy branch at all.
|
|
131
|
+
#
|
|
132
|
+
# READING THE STREAM SPENDS IT — the same constraint the deletion guard above
|
|
133
|
+
# documents, and the same remedy: capture, use, replay with `exec <`. If no
|
|
134
|
+
# scratch file can be created this stands down without reading a byte, leaving
|
|
135
|
+
# the hook exactly as it was; a guard that cannot read the stream must not also
|
|
136
|
+
# starve the checks that can.
|
|
137
|
+
# ---------------------------------------------------------------------------
|
|
138
|
+
#
|
|
139
|
+
# The `-f` test is not belt and braces. This is now the FIRST thing in the file
|
|
140
|
+
# to invoke the validator, so a checkout where no candidate path exists would
|
|
141
|
+
# fail every push with a Node module-resolution error instead of the hook's own
|
|
142
|
+
# message. Standing down leaves that diagnosis to the traceability step below,
|
|
143
|
+
# which owns it and words it properly.
|
|
144
|
+
LISA_DEST_REFS="$(mktemp "${TMPDIR:-/tmp}/lisa-dest-refs.XXXXXXXX")" || LISA_DEST_REFS=""
|
|
145
|
+
if [ -n "$LISA_DEST_REFS" ] && [ -f "$WORK_ITEM_SCRIPT" ]; then
|
|
146
|
+
cat > "$LISA_DEST_REFS"
|
|
147
|
+
if ! node "$WORK_ITEM_SCRIPT" validate-push-destination "${1:-origin}" --refs "$LISA_DEST_REFS"; then
|
|
148
|
+
rm -f "$LISA_DEST_REFS"
|
|
149
|
+
exit 1
|
|
150
|
+
fi
|
|
151
|
+
# Put the stream back, byte for byte, for the validator and every gate below.
|
|
152
|
+
exec < "$LISA_DEST_REFS"
|
|
153
|
+
# Unlinked while the descriptor above is still open, so nothing is left in
|
|
154
|
+
# TMPDIR and no later `trap ... EXIT` in this file can drop the cleanup.
|
|
155
|
+
rm -f "$LISA_DEST_REFS"
|
|
156
|
+
fi
|
|
157
|
+
unset LISA_DEST_REFS
|
|
158
|
+
# END: push destination guard
|
|
159
|
+
|
|
90
160
|
# ---------------------------------------------------------------------------
|
|
91
161
|
# Work-item traceability, at the push moment.
|
|
92
162
|
#
|