@amsterdamdatalabs/adl-agent-control-linux-x64 0.1.8 → 0.1.9

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/bin/adl CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/bin/adl
3
3
  size: 82920928 bytes
4
- sha256: ecd5111c7bc2c06d56361450a0d97b8280f6d300f879714a0bd23d2c534ec61b
4
+ sha256: 74d2d0af04a268afff30746e0d68d9d49d8e92c347e913330393c90362c99aff
package/bin/git CHANGED
@@ -621,8 +621,76 @@ case "$command_name" in
621
621
  *) exec "$real_git" ${args[@]+"${args[@]}"} ;;
622
622
  esac
623
623
 
624
+ # Whether option ARG, for network subcommand SUB, consumes the NEXT argv
625
+ # element as its value. Incident 2026-09-30 (Azure DevOps push 16505 recorded
626
+ # as the HUMAN "Tarun Rana" for an agent session's `git push -u origin
627
+ # feat/adl-install`): one shared value-option list treated `-u` as taking a
628
+ # value for EVERY subcommand. It only does for ls-remote/clone
629
+ # (`--upload-pack <exec>`); for push it is `--set-upstream` and for fetch/pull
630
+ # `--update-head-ok`, both flags. `origin` was swallowed as the "value",
631
+ # `feat/adl-install` became the "remote", `remote get-url` failed, and the
632
+ # push went to plain git and the human's credential helper. The table is
633
+ # therefore PER SUBCOMMAND (verified against git-push/fetch/pull/ls-remote/
634
+ # clone(1)). Options whose argument is optional (`--force-with-lease`,
635
+ # `--recurse-submodules` on fetch/pull/clone, `-S`, `-r`) only take it
636
+ # attached (`--opt=value`) and so never consume the next element.
637
+ network_option_takes_value() {
638
+ local sub="$1" arg="$2" short_values long_values chars i ch
639
+ local fetch_long=' depth deepen shallow-since shallow-exclude negotiation-tip negotiation-restrict negotiation-include filter refmap jobs server-option upload-pack exec submodule-prefix recurse-submodules-default bundle-uri '
640
+ case "$sub" in
641
+ push) short_values='o'; long_values=' push-option receive-pack exec repo recurse-submodules ' ;;
642
+ fetch) short_values='jo'; long_values="$fetch_long" ;;
643
+ pull) short_values='josX'; long_values="$fetch_long strategy strategy-option cleanup into-name " ;;
644
+ ls-remote) short_values='ou'; long_values=' upload-pack exec server-option sort ' ;;
645
+ clone) short_values='obucj'; long_values=' origin branch upload-pack template config separate-git-dir ref-format jobs bundle-uri depth shallow-since shallow-exclude reference reference-if-able server-option filter revision object-format ' ;;
646
+ *) return 1 ;;
647
+ esac
648
+ case "$arg" in
649
+ --|--*=*) return 1 ;;
650
+ --*) [[ "$long_values" == *" ${arg#--} "* ]] ;;
651
+ -?) [[ "$short_values" == *"${arg#-}"* ]] ;;
652
+ -*)
653
+ # Clustered short options (`-uf`, `-fo x`): the first value-taking
654
+ # letter ends the cluster; it consumes the next element only when it is
655
+ # the LAST letter (otherwise the rest of the cluster is its value).
656
+ chars="${arg#-}"
657
+ for ((i = 0; i < ${#chars}; i += 1)); do
658
+ ch="${chars:i:1}"
659
+ if [[ "$short_values" == *"$ch"* ]]; then
660
+ ((i == ${#chars} - 1)) && return 0
661
+ return 1
662
+ fi
663
+ done
664
+ return 1
665
+ ;;
666
+ *) return 1 ;;
667
+ esac
668
+ }
669
+
670
+ # True when OPERAND (an unresolved would-be remote name) is really a local
671
+ # path or a URL, which plain git handles without any named remote: an
672
+ # absolute/relative/home path, an existing path (relative to any leading
673
+ # `-C <dir>`), a `scheme://` URL, or scp-like `host:path`.
674
+ is_path_or_url_operand() {
675
+ local operand="$1" base='' i
676
+ case "$operand" in
677
+ /*|./*|../*|~*|.|..|*://*) return 0 ;;
678
+ esac
679
+ is_scp_like_url "$operand" && return 0
680
+ for ((i = 0; i < command_index; i += 1)); do
681
+ if [[ "${args[i]}" == -C && $((i + 1)) -lt command_index ]]; then
682
+ case "${args[i + 1]}" in
683
+ /*) base="${args[i + 1]}" ;;
684
+ *) base="${base:+$base/}${args[i + 1]}" ;;
685
+ esac
686
+ fi
687
+ done
688
+ [[ -e "${base:+$base/}$operand" ]]
689
+ }
690
+
624
691
  remote_url=''
625
692
  remote_name='origin'
693
+ remote_explicit=0
626
694
 
627
695
  # A direct URL is authoritative for every network command. Scan it before
628
696
  # resolving a remote name so clone, ls-remote, and explicit fetch/push/pull URLs never
@@ -635,24 +703,27 @@ for ((index = command_index + 1; index < ${#args[@]}; index += 1)); do
635
703
  done
636
704
 
637
705
  if [[ -z "$remote_url" ]]; then
638
- # The first positional argument to fetch, pull, push, and ls-remote is the selected
639
- # remote. Skip the common options that carry a following value; unknown
640
- # options are skipped rather than treated as a remote name.
706
+ # The first positional argument to fetch, pull, push, and ls-remote is the
707
+ # selected remote. Skip options (and the value of those that take one FOR
708
+ # THIS SUBCOMMAND, see network_option_takes_value); other options are
709
+ # skipped rather than treated as a remote name.
641
710
  for ((index = command_index + 1; index < ${#args[@]}; index += 1)); do
642
711
  argument="${args[index]}"
643
712
  case "$argument" in
644
713
  --)
645
714
  ((index += 1))
646
- ((index < ${#args[@]})) && remote_name="${args[index]}"
715
+ if ((index < ${#args[@]})); then
716
+ remote_name="${args[index]}"
717
+ remote_explicit=1
718
+ fi
647
719
  break
648
720
  ;;
649
- -c|-j|-o|-u|--depth|--deepen|--filter|--jobs|--negotiation-tip|--push-option|--receive-pack|--refmap|--recurse-submodules|--server-option|--shallow-exclude|--shallow-since|--strategy|--strategy-option|--upload-pack)
650
- ((index += 1))
651
- ;;
652
- -?*|--*=*)
721
+ -?*)
722
+ network_option_takes_value "$command_name" "$argument" && ((index += 1))
653
723
  ;;
654
724
  *)
655
725
  remote_name="$argument"
726
+ remote_explicit=1
656
727
  break
657
728
  ;;
658
729
  esac
@@ -661,6 +732,16 @@ fi
661
732
 
662
733
  if [[ -z "$remote_url" ]]; then
663
734
  if ! remote_url="$("$real_git" "${args[@]:0:command_index}" remote get-url "$remote_name" 2>/dev/null)"; then
735
+ # FAIL CLOSED (incident 2026-09-30, above): an EXPLICITLY named remote
736
+ # that does not resolve, and is not a local path or a URL, must never be
737
+ # handed to plain git -- it would authenticate as the human via the
738
+ # keychain/credential helper if the name was really an Azure DevOps
739
+ # remote we mis-scanned. clone has no remote name (its operand is the
740
+ # source), and an unnamed default remote keeps today's pass-through.
741
+ if [[ "$command_name" != clone && "$remote_explicit" == 1 ]] && ! is_path_or_url_operand "$remote_name"; then
742
+ printf "git: cannot resolve remote '%s' for %s; refusing to pass an unresolved remote to plain git (it may authenticate as the human)\n" "$remote_name" "$command_name" >&2
743
+ exit 1
744
+ fi
664
745
  exec "$real_git" ${args[@]+"${args[@]}"}
665
746
  fi
666
747
  fi
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amsterdamdatalabs/adl-agent-control-linux-x64",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "adl CLI binary for linux/x64 (agent identity + Azure DevOps front door — see docs/architecture/cli-design.md)",
5
5
  "license": "UNLICENSED",
6
6
  "os": [
@@ -206,7 +206,9 @@ export const REPO_STANDARD = {
206
206
  allow: ["genericContribute", "pullRequestContribute"],
207
207
  deny: ["forcePush", "policyExempt", "pullRequestBypassPolicy"],
208
208
  },
209
- "agent-reviewer": { allow: ["pullRequestContribute"], deny: ["genericContribute"] },
209
+ // Tarun, 2026-09-30: no agent gets force push — agent-reviewer included,
210
+ // in every project (only its genericContribute deny is Enact-only).
211
+ "agent-reviewer": { allow: ["pullRequestContribute"], deny: ["genericContribute", "forcePush"] },
210
212
  } as Record<string, { allow: readonly PermissionBitName[]; deny: readonly PermissionBitName[] }>,
211
213
  /**
212
214
  * The project's build service identity (display name `Build\<projectId>`,
@@ -214,12 +216,17 @@ export const REPO_STANDARD = {
214
216
  * — Tarun, 2026-09-27, cross-checked against
215
217
  * /Users/tarunrana/Documents/ADL-ISMS-Policies/.scratchpad/ci_build_service_grant.py,
216
218
  * which grants exactly these bits on adl-agent-control). CI needs to push
217
- * tags/branches and complete PRs on the repo, and needs PolicyExempt only
218
- * on `integration` (so a version-bump commit made by CI itself is not
219
+ * and complete PRs on the repo, and needs PolicyExempt only on
220
+ * `integration` (so a version-bump commit made by CI itself is not
219
221
  * blocked by its own policies) — never on `main`.
222
+ *
223
+ * NOT forcePush (Tarun, 2026-09-30): the bump is a plain fast-forward
224
+ * `git push origin HEAD:integration`; agent-identities' build service has
225
+ * no ForcePush and bumped 0.4.2 → 0.4.3 fine. The grant script's
226
+ * ForcePush has no consumer, so force push is required of no identity.
220
227
  */
221
228
  buildService: {
222
- repo: { allow: ["genericContribute", "forcePush", "pullRequestContribute"] } as {
229
+ repo: { allow: ["genericContribute", "pullRequestContribute"] } as {
223
230
  allow: readonly PermissionBitName[];
224
231
  },
225
232
  integrationRef: { allow: ["policyExempt"] } as { allow: readonly PermissionBitName[] },
@@ -9,6 +9,11 @@ set -euo pipefail
9
9
  # triggering another pipeline run. No npm query, no second PR, no second
10
10
  # test run (Tarun, 2026-09-29).
11
11
 
12
+ # CI never carries an agent identity: the push below authenticates as the
13
+ # project build service through the checkout's persisted System.AccessToken.
14
+ # Never set an agent identity here, and never inherit one from the caller.
15
+ unset ADL_AGENT_ID_AGENT
16
+
12
17
  die() {
13
18
  echo "version-bump: $*" >&2
14
19
  exit 1
@@ -185,5 +190,5 @@ fi
185
190
  git -C "$repo_root" add -A
186
191
  git diff --cached --quiet && die "version bump produced no staged change (expected at least $version_file)"
187
192
  git commit -m "chore: bump version $current_version to $next_version ***NO_CI***"
188
- ADL_AGENT_ID_AGENT=agent-tarun git push origin "HEAD:$integration_branch"
193
+ git push origin "HEAD:$integration_branch"
189
194
  echo "Bumped $version_file from $current_version to $next_version on $integration_branch."